ELEX 4653 Lab 2¶

This lab provides practice on expressions, lists, dictionaries, control flow statements and functions.

Instructions:

  • Modify this notebook by adding the Python code described below.

  • Test your code using the menu item Cell ► Run All

  • Save the notebook (the .ipynb file) and upload it to the appropriate Assignment folder on the course web site.

Question 1¶

Write a function, substrings(s) that returns a list containing all possible initial substrings from s in increasing length. For example if s is "abc123" then substrings(s)should return ['a', 'ab', 'abc', 'abc1', 'abc12', 'abc123'].

In [1]:
def substrings(s):
    l=[]
    for i in range(1,len(s)+1):
        l.append(s[0:i])
    return l

def substrings(s):
    return [s[:n+1] for n in range(len(s))]

substrings("abc123")
Out[1]:
['a', 'ab', 'abc', 'abc1', 'abc12', 'abc123']

Question 2¶

Write a function, reverseif(l,p), where l is a list of strings and a p is a list of booleans. The function should return a list whose i'th element is:

  • l[i] if p[i] is False, or
  • l[i] with the order of the characters reversed if p[i] is True.

For example, reverseif(['abc', '123', 'xyzzy', 'zebra'], [True, False, False, True])should return ['cba', '123', 'xyzzy', 'arbez'].

In [2]:
def reverseif(l,p):
    r = []
    for i,s in enumerate(l):
        if p[i]:
            r.append(s[::-1])
        else:
            r.append(s)
    return r

def reverseif(l,p):
    return [s[::-1] if r else s for s,r in zip(l,p)]

reverseif(['abc', '123', 'xyzzy', 'zebra'], [True, False, False, True])
Out[2]:
['cba', '123', 'xyzzy', 'arbez']

Question 3¶

Write a function, removechars(s,x), that returns a set of the characters in the string s that are not in the string x.

For example, removechars('giraffe',"aeiou")should return {'g', 'r', 'f'} (with the items in any order).

In [3]:
def removechars(s,x):
    return set(s)-set(x)

removechars('giraffe',"aeiou")
Out[3]:
{'f', 'g', 'r'}

Question 4¶

Write a function sumvalues(d) that returns a dictionary whose items have the keys in the dictionary d and whose values are the sums of the iterable values in d. For example, if d is {32:(1,2,3), 'xyz':{4,5,6}, (1,2):[5,9,10,11]} then sumvalues(d) should return {32:6, 'xyz':15, (1,2):35}.

In [4]:
def sumvalues(d):
    r = {}
    for k,v in d.items():
        for i,s in enumerate(v):
            rv = s if not i else rv+s
        r[k]=rv
    return r

def sumvalues(d):
    return {k:sum(v) for k,v in d.items()}

d={32:(1,2,3), 'xyz':{4,5,6}, (1,2):[5,9,10,11]}
sumvalues(d)
Out[4]:
{32: 6, 'xyz': 15, (1, 2): 35}

Question 5¶

Write a function toggletype(x) that toggles the type of x and each item in x. For this question toggle means to change the type of the object from list to tupple or vice-versa. For example, toggletype(([1,2,3],('ab','c'),("hello",))) would return [(1,2,3),['a','b'],["hello"]] and toggletype([(1,2,3),['ab','c'],["hello"]]) would return ([1, 2, 3], ('ab', 'c'), ('hello',)).

In [5]:
def toggletype(x):
    l=[]
    for i in x:
        if type(i) == list:
            l.append(tuple(i))
        else:
            l.append(list(i))
    return l if type(x) == tuple else tuple(l)

toggletype(([1,2,3],('ab','c'),("hello",)))
Out[5]:
[(1, 2, 3), ['ab', 'c'], ['hello']]
In [6]:
# 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=randwords(1,nl=(5,8))[0]
        os=copy.deepcopy(s)
        l=substrings(s)
        assert(len(l) == len(os)), f"substrings({os}) returns {l}"
        cl=[l[i][i] for i in range(len(l))]
        assert os == ''.join(cl), f"substrings({os}) returns {l}"

    def q2():
        l = randwords(randint(5,8),nl=(2,5))
        p = [randint(0,1) for s in l]
        ol, op = copy.deepcopy(l), copy.deepcopy(p)
        assert all([s == ''.join(reversed(ol[i])) if op[i] else ol[i] for i,s in enumerate(reverseif(l,p))]), \
            f"reverserif({ol},{op}) returns {l}"

    def q3():
        s = randwords(1,nl=(10,15))[0]
        x = randwords(1,nl=(10,15))[0]
        os = copy.deepcopy(s)
        ox = copy.deepcopy(x)
        r = removechars(s,x)
        assert all([(l in x and (l not in r)) or (l not in x and (l in r)) for l in os]), \
            f"removechars({os},{ox}) returns {r}"
    
    def q4():
        k=randwords(randint(2,4))+[randint(1,999) for i in range(randint(2,4))]
        random.shuffle(k)
        v=[[randint(-1,9) for i in range(randint(2,4))] for i in range(len(k))]
        v=[set(x) if randint(0,1) else x for x in v]
        d=dict(zip(k,v))
        od=copy.deepcopy(d)
        r = sumvalues(d)

        assert len(r) == len(od) and all([v == sum(od[k]) for k,v in r.items()]), \
            f"sumvalues({od}) returns {r}"

    def q5():
        l=[randwords(randint(2,3)) for l in range(randint(3,6))]
        l=[tuple(x) if randint(0,1) else x for x in l]
        l=tuple(l) if randint(0,1) else l
        ol=copy.deepcopy(l)
        l=toggletype(l)
        assert len(l) == len(ol) and \
            not ({list,tuple} ^ {type(l),type(ol)}) and \
            all([not ({list,tuple} ^ {type(x),type(ol[i])}) for 
                 i,x in enumerate(l)]), f"toggletype({ol}) returns {l}"
           
    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.
Question 5 OK.