ELEX 4653 Exam 4¶

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 Question n OK. at the bottom of the notebook means that no errors were found in your answer to question n.

  • When your are done or when the exam time is over, save the notebook (the .ipynb file) and upload it to the appropriate Assignment folder on the course web site.

Question 1¶

Write a function named myfilter(s) where s is a set of strings. The function should return any item in s whose first letter is the same as its last letter.

For example, myfilter({'a', 'xyzzyx', 'abc', 'de'}) would return either a or xyzzyx.

In [1]:
def myfilter(s):
    for w in s:
        if w[0] == w[-1]:
            return w

def myfilter(s):
    w = s.pop()
    return w if w[0] == w[-1] else myfilter(s)

myfilter({'a', 'xyzzyx', 'abc', 'de'})
Out[1]:
'a'

Question 2¶

Write a function, correct(d) where d is a dictionary whose values are tuples of two integers. The function should return a list of the keys for which the corresponding tuples are in increasing order.

For example, correct({"ball":(1,2), "bat":(3,3), "Jane":(-1,5), "red":(9,1)}) should return ['ball', 'Jane'].

In [2]:
def correct(d):
    sum = 0
    l = []
    for k in d:
        if d[k][0] < d[k][1]:
            l += [k]
    return l

def correct(d):
    return [k for k,v in d.items() if v[0]<v[1]]

correct({"ball":(1,2), "bat":(3,3), "Jane":(-1,5), "red":(9,1)})
Out[2]:
['ball', 'Jane']

Question 3¶

Write a function named reverseval(l) where l is a list of strings. The function should return a dictionary whose keys are the values in l and whose values are the keys with the order of the letters reversed.

For example, reverseval(['bcd', 'a', 'zebra']) would return {'bcd': 'dcb', 'a': 'a', 'zebra': 'arbez'}.

In [3]:
def reverseval(l):
    r = {}
    for k in l:
        r[k] = k[::-1]
    return r

def reverseval(l):
    return {k:k[::-1] for k in l}

reverseval(['bcd', 'a', 'zebra'])
Out[3]:
{'bcd': 'dcb', 'a': 'a', 'zebra': 'arbez'}

Question 4¶

Define a string mypat that is regular expression that matches a string that:

  • starts with the string CFR
  • followed by one to three digits
  • followed by a period
  • followed by at least one of the characters I, V, X, L or C

For example, your pattern should match the strings CFR47.IVL" or 'CFR1.C' but not 'CF1.L' or 'CFR1234.C' or 'CFR123 I' or 'CFR123.'.

Your answer in the cell below should be an assignment to the variable mypat. For example, your answer might look like:

mypat = r'A{3}x+--'  # not the corect answer
In [4]:
mypat = r'CFR\d{1,3}\.[IVXLC]+'    
In [5]:
# lab validation code; do not modify
def labcheck():
    import copy, random, re, string, types
    from random import randint
            
    def checkre(pat,ok,nok):
        for s in ok:
            assert re.fullmatch(pat,s), \
                f"pattern '{pat}'\n did not match string '{s}'"
        for s in nok:
            assert not re.fullmatch(pat,s), \
                f"pattern '{pat}'\n matched string '{s}'"  

    def randwords(n,chars=string.ascii_lowercase,nl=(2,5)):
        l = set()
        while len(l)<n:
            l |= set((''.join([chars[randint(0,len(chars)-1)] for i in range(randint(*nl))]),))
        return list(l)

    def q1():
        s = set([w for w in [randwords(1)[0] for i in range(10)] if w[0] != w[-1]])
        w = s.pop()
        w = w+w[0]
        s.add(w)
        ow, os = copy.deepcopy(w), copy.deepcopy(s)
        r = myfilter(s)
        assert r in os and r == ow,f"myfilter({os}) returns {r}"
        
    def q2():
        n=randint(5,8)
        l=list(set(randwords(100)))[0:n]
        t=[(randint(-1,3),randint(-1,3)) for i in range(n)]
        d=dict(zip(l,t))
        od = copy.deepcopy(d)
        r = correct(d)
        ret = set(r)
        assert all([od[k][0]<od[k][1] for k in r]) and \
            all([od[k][0]>=od[k][1] for k in set(l)-set(r)]),f"correct({od}) returns {r}"
    
    def q3():
        n=randint(5,8)
        l=randwords(n)
        ol = copy.deepcopy(l)
        r = reverseval(l)
        assert all([list(k) == list(reversed(v)) for k,v in r.items()]) and set(r) == set(ol), \
            f"reverseval({ol}) returns {r}"

    def q4():
        ok = [ ('CFR'+
            randwords(1,string.digits,(1,3))[0] +
            '.' +
            randwords(1,"IVXLC",(1,5))[0] )
                  for i in range(randint(5,7)) ]
        nok = "CF1.L C.L CFR.C CFR1234.C CFR123_I CFR123.".split()
        checkre(mypat,ok,nok)    
        
    for s,i in [(s,s[1:]) for s in locals().keys() if re.search(r'q\d+',s)]:
        try:
            locals()[s]()
            print(f"Question {i} OK.")
        except Exception as e:
            print(f"Failed check for Question {i}: {e}")
            
labcheck()
Question 1 OK.
Question 2 OK.
Question 3 OK.
Question 4 OK.