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

  • Comment out any code that causes errors and re-run Cell ► Run All before submitting your notebook.

  • 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 growing that takes an argument named x that is a list of floats. Your function should return a list containing the value 1 for each element that is smaller than the next one and 0 for each value that is not. For example, if x=[1, -1, 3, 0, 1] growing(x) should return a list containing [0, 1, 0, 1]. Note that the returned list will be one element shorter than the argument.

In [1]:
def growing(x):
    return [1 if x[i]>x[i-1] else 0 for i in range(1,len(x))]

x=[1, -1, 3, 0, 1]
growing(x)
Out[1]:
[0, 1, 0, 1]

Question 2

Write a function named sel2 that takes one dictionary argument named d. The keys of the dictionary d are strings and the values are lists of integers. Your function should create a new dictionary that has the same keys but each list replaced by the second integer in the corresponding list. For example if d = { 'a': [1, 3, 2], 'bb':[8, -1], 'f': [3, 11, 8, 8]} then sel2(d) should return the dictionary {'a': 3, 'bb': -1, 'f': 11}.

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

d = { 'a': [1, 3, 2], 'bb':[8, -1], 'f': [3, 11, 8, 8]}
sel2(d)
Out[2]:
{'a': 3, 'bb': -1, 'f': 11}

Question 3

Write a recursive function named rint2str that takes an argument named l which is a list of integers and returns a list of strings. For example if l=[0, 1, -3] then rint2str(l) would return ['0', '1', '-3'].

In [3]:
def rint2str(l):
    if not l:
        return l
    else:
        return [str(l[0])]+rint2str(l[1:])
        
l=[0, 1, -3]
rint2str(l)
Out[3]:
['0', '1', '-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 MGA or ADA
  2. three or four digits
  3. the letters YK, BRU or CRU
  4. the letter S or T
  5. optionally the letter Z
  6. optionally the characters -REEL7

For example, re.search(pat,'MGA1234YKSZ-REEL7') would return a match object but re.search(pat,'MGB1234YKSZ-REEL7') would not.

In [4]:
pat=r'^(MGA|ADA)\d{3,4}(YK|BRU|CRU)[ST]Z?(-REEL7)?$'

import re
print(re.search(pat,'MGA1234YKSZ-REEL7'))
print(re.search(pat,'MGB1234YKSZ-REEL7'))                
<_sre.SRE_Match object; span=(0, 17), match='MGA1234YKSZ-REEL7'>
None
In [5]:
# exam validation code; do not modify
def examcheck():
    import copy, hashlib, re
    from random import randint, choices, shuffle, sample
    
    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():
        import random
        n=randint(5,9)
        x=[random.random()*100 for _ in range(n)]
        x0=copy.copy(x)
        y=growing(x)
        assert len(y) == n-1 and all([a<b for a,b,t in zip(x0,x0[1:],y) if t]), \
            "growing({}) returns: {}".format(x0,y)

    def q2():       
        n=randint(3,5)
        wl=randwords(n)
        nl=[sample(range(10,100),k=randint(3,5)) for i in range(n)]
        d={k:v for k,v in zip(wl,nl)}
        d0=copy.deepcopy(d)
        y=sel2(d)
        assert len(y) == n and set(d0.keys()) == set(y.keys()) and \
            all([y[k] == d0[k][1] for k in d0]), "sel2({}) returns {}".format(d0,y)

    def q3():
        n=randint(3,5)
        l=sample(range(-9,9),k=n)
        l0=copy.copy(l)
        y=rint2str(l)
        checkrecursive(rint2str)
        assert len(y) == n and all((type(i) == str for i in y)) and \
                all((int(s) == i for i,s in zip(l0,y))), \
                "rint2str({}) returns {}".format(l0,y)
          
  
    def q4():
        ok=['MGA1234YKSZ-REEL7', 'ADA1234YKSZ-REEL7', 'MGA999YKSZ-REEL7', 
            'MGA1234BRUSZ-REEL7', 'MGA1234CRUSZ-REEL7', 'MGA1234YKTZ-REEL7',
            'MGA1234YKT-REEL7', 'MGA1234YKT']
        nok=[' MGA1234YKSZ-REEL7', 'MGB1234YKSZ-REEL7', 'MGA12YKSZ-REEL7', 
            'MGA1234YSZ-REEL7', 'MGA1234YKA-REEL7', 'MGA1234YKSZ-REEL' ]
        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.