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.
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']
.
def substrings(s):
return [s[:i] for i in range(1,len(s)+1)]
substrings("abc123")
['a', 'ab', 'abc', 'abc1', 'abc12', 'abc123']
Write a function, reverseif(l,p)
, where l
is a list of str
ings and a p
is a list of bool
eans. The function should return a list whose i'th element is:
l[i]
if p[i]
is False
, orl[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']
.
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])
['cba', '123', 'xyzzy', 'arbez']
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).
def removechars(s,x):
return set(s)-set(x)
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}
.
def sumvalues(d):
return {k:sum(v) for k,v in d.items()}
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 tuple 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',))
.
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"]])
toggletype(([1,2,3],('ab','c'),("hello",)))
[(1, 2, 3), ['ab', 'c'], ['hello']]
# lab validation code; do not modify
def labcheck(testing=0,ntest=10):
'''
Python exercise checking.
Ed.Casas 2023-5-22
Calls functions q<n>* and checks HMAC of return value[0].
On mismatch prints return value[1] (function, arguments and return values).
Setting testing=1 prints HMACs of correct results; paste into 'hashvalues'.
Note:
If q<n>* result not JSON-able, convert to string.
Result order matters for comparison. Sort result if ordering not important.
'''
import base64, copy, hashlib, json, random, re, string, types
from random import randint
# compare regex to strings that should/shouldn't match
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}'"
# list of n words with nl letters from chars without repeats
def randwords(n,chars=string.ascii_lowercase,nl=(2,5)):
l = []
while len(l)<n:
w = ''.join([chars[randint(0,len(chars)-1)] for i in range(randint(*nl))])
if w not in l:
l.append(w)
return l
# convert sets to dicts and dict keys to strings so they can be sorted
def orderkeys(o):
if isinstance(o,set):
return {str(k):None for k in o}
if isinstance(o,dict):
return {str(k):orderkeys(v) for k,v in o.items()}
return o
def Q1():
s=randwords(1,nl=(5,8))[0]
os=copy.deepcopy(s)
l=substrings(s)
return l,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)
r = reverseif(l,p)
return r,f"reverserif({ol},{op}) returns {l}"
def Q3():
s = randwords(1,nl=(10,15))[0]
x = randwords(1,nl=(10,15))[0]
os, ox = copy.deepcopy(s), copy.deepcopy(x)
r = removechars(s,x)
return r,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)
return r,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)
r=toggletype(l)
return r,f"toggletype({ol}) returns {r}"
hashvalues = '''
N0seoh5a0d2KRdWGvbk3Z7anaQs6Ydfgm0C1MgQl
b8xYzKTFDNI/TovITOaltwp4nFejKrY25nPjnDVf
YPuAxb+6Bc80Hz5CGnFAMfmM+emnzb25X2GoLy7L
6wyDQqTOu5TI5VpYAS8Ch5RZfWLeT7lfkJXVR2cu
dEIzYl5qK7EWXFR5ixmkq2IwzIo8Q4tlQ+K9MlSB
'''.split()
newhash = ''
dsize = 3 # HMAC base64 digest size (bytes, use 3 or 6 for 4 or 8 char digests)
dlen = ((dsize*8+5)//6+3)//4*4
for n,f in [(n,f) for n,f in locals().items() if callable(f) and re.search(r'^[Qq]\d+.*',n)]:
random.seed(n)
hashes = '0'*dlen*ntest if testing else hashvalues.pop(0)
err = ''
while hashes and not err:
h, hashes = hashes[:dlen], hashes[dlen:]
try:
v,s = f()
b = json.dumps(orderkeys(v),sort_keys=True).encode()
c = base64.b64encode(hashlib.blake2b(b,digest_size=dsize).digest()).decode()
if testing:
print(s)
newhash += c
else:
if c != h:
err = f"Wrong result for test {n}: {s} (HMAC={c} instead of {h})"
except Exception as e:
err = f"Error during test {n}: {e}"
if testing:
newhash += '\n'
else:
print(err or f"Passed test {n}.")
if testing:
print(newhash)
labcheck()
Passed test Q1. Passed test Q2. Passed test Q3. Passed test Q4. Passed test Q5.