ELEX 4653 Lab 4¶

The lab deals with importing modules, sorting, and working with container types.

  • Version 2 (fixed error in Q1 marking code).
  • Version 3 (corrected codec to codecs in Q1).

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¶

  • Import the random package.
  • Import the datetime package into the dt namespace.
  • Import the codecs.encode() and codecs.decode() functions from the codecs package into the global namespace.

These should enable the following expressions (among many others) to be evaluated:

  • print(random.randint(0,10))
  • print(dt.datetime(1986,12,25).strftime("%c"))
  • print(*encode("😀"),decode(bytes([240,159,152,128])),"\U0001f600")
In [1]:
import random
import datetime as dt
from codecs import encode, decode

print(random.randint(0,10))
print(dt.datetime(1986,12,25).strftime("%c"))
print(*encode("😀"),decode(bytes([240,159,152,128])),"\U0001f600")
8
Thu Dec 25 00:00:00 1986
240 159 152 128 😀 😀

Question 2¶

Write a function sortchars(l) that sorts a list l containing dictionaries. Each dictionary has key name with a string value and a key age with a numeric value. Your function should return a list of the dictionaries ordered by increasing age.

For example, if l=[{'name':'Thor','age':32},{'name':'Erik','age':42},{'name':'Carol','age':29}] then calling sortchars(l) should return the list [{'name': 'Carol', 'age': 29}, {'name': 'Thor', 'age': 32}, {'name': 'Erik', 'age': 42}]. Hint: sorted(l,key=...).

In [2]:
def sortchars(l):
    return sorted(l,key=lambda d:d['age'])


l=[{'name':'Thor','age':32},{'name':'Erik','age':42},{'name':'Carol','age':29}]
print(sortchars(l))
[{'name': 'Carol', 'age': 29}, {'name': 'Thor', 'age': 32}, {'name': 'Erik', 'age': 42}]

Question 3¶

Write a function ordpair(l) that takes a list l with an even number of two-element tuples containing a string and a numeric value. The function first sorts the list in increasing order of the numeric value and then returns a list of tuples containing pairs of the values taken in order.

For example, if l=[('a',5),('b',2),('c',3),('d',0)] then fairpair(l) returns [('d','b'),('c','a')].

In [3]:
def ordpair(l):
    sl=[t[0] for t in sorted(l,key=lambda t:t[1])]
    return list(zip(sl[::2],sl[1::2]))[:len(l)//2]

# or

def ordpair(l):
    l.sort(key=lambda x:x[1])
    r=[]
    for i in range(0,len(l),2):
        r.append( (l[i][0],l[i+1][0]))
    return r

l=[('a',5),('b',2),('c',3),('d',0)]
ordpair(l)
Out[3]:
[('d', 'b'), ('c', 'a')]

Question 4¶

Write a function spellcheck(s,d) that splits the string s using str.split() and returns a list of all the "words" in s that do not appear in the set d.

For example, spellcheck("apple ball cat",{"apple", "bib", "cat"}) would return ["ball"]. Mis-spelled words may be returned in any order and one (or more) times if they appear more than once in s.

In [4]:
def spellcheck(s,d):
    return list(set(s.split())-d)

# or

def spellcheck(s,d):
    l=[]
    for w in s.split():
        if w not in d:
            l.append(w)
    return l
        
spellcheck("apple ball cat",{"apple", "bib", "cat"})
Out[4]:
['ball']
In [5]:
# lab validation code; do not modify
def labcheck():
    import random, copy, re

    def q1():
        assert 'random' in globals(), "random not imported"
        assert 'dt' in globals() and 'date' in dir(dt), "datetime not imported into dl"
        import codecs
        assert 'encode' in globals() and encode is codecs.encode, "encode() not global"
        assert 'decode' in globals() and decode is codecs.decode, "decode() not global"

    def q2():
        import random
        from random import randint
        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)

        n=randint(3,5)
        w=randwords(n)
        x=[random.randint(18,40) for i in range(n)]
        l=[{'name':n,'age':a} for n,a in zip(w,x)]
        ol=copy.deepcopy(l)
        r=sortchars(l)
        assert all([r[i-1]['age']<=r[i]['age'] for i in range(1,n)]), \
            f"sortpoints({ol})\nreturns:\n{r}"
        
    def q3():
        import random
        from random import randint
        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 randnums(n):
            l = set()
            while len(l)<n:
                l |= set((randint(97,122),))
            return list(l)
        n=randint(2,3)
        l=list(zip(randwords(n),randnums(n)))
        random.shuffle(l)
        ol=copy.deepcopy(l)
        r=ordpair(l)
        from itertools import chain
        o=list(chain(*r))
        d=dict(ol)
        assert all([d[o[i-1]]<d[o[i]] for i in range(1,len(o))]), \
            f"fairpair({ol}) returns {r}"
        
    def q4():
        import random
        from random import randint
        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)
        d=randwords(5)
        x=randwords(3)
        l=d+x
        random.shuffle(l)
        s=" ".join(l)
        od=copy.deepcopy(d)
        r=spellcheck(s,d)
        # r=['x']
        assert set(r) == set(x), f"spellcheck('{s}',{od}) returns {r}"

    
    
    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.