This lab provides practice looking up built-in functions and using iterators and exceptions.
Version 2: compatible with Python 3.7.
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.
The documentation in the Built-in Functions section of the Python Standard Library documentation describes Python's built-in functions.
Define a tuple named builtins
where each element is a Python function that:
returns an object that allows you to read from a file
creates an object that can only take on values True
or False
returns a single-character string corresponding to a Unicode value
returns the memory address of an object (at least, in the CPython implementation of Python)
For example, your answer might look like:
builtins = (hash,help,hex,tuple)
The entries in the tuple should be the functions, not the names of the functions as strings.
builtins = (open,bool,chr,id)
Write a function counttrue(i)
that returns the number of values returned by the iterable object i
that are logically true.
For example, counttrue([True, False, '', {1}]+list(range(-3,3)))
should return 7.
Note: The argument i
is iterable, but it is not a list.
def counttrue(i):
n=0
for x in i:
n += 1 if x else 0
return n
def counttrue(i):
return sum(map(lambda x: 1 if x else 0,i))
Write a function, nrep(n,c)
where n
is an iterable returning integers and c
is an iterable returning characters. The function should return a list of strings in which each string is the letter returned by the second iterable repeated the number of times returned by the first iterable.
For example, nrep([3,0,1],"abc")
should return ['aaa', '', 'c']
.
Note: n
and c
are iterables but not lists or strings.
def nrep(n,c):
return [a*b for a,b in zip(n,c)]
nrep([3,0,1],"abc")
['aaa', '', 'c']
Write a function stable(c)
that returns the magnitude of the complex value c
if it is less than one or raises the ValueError exception otherwise.
For example if stable(0.5+0.5j)
would return 0.7071... but stable(1+0.5j)
would raise exception ValueError.
def stable(c):
r = abs(c)
if r < 1:
return r
else:
raise ValueError
for s in (0, 0.5+0.5j, 1+0.5j):
try:
print(stable(s))
except ValueError:
pass
0 0.7071067811865476
Write a function rerun(f,n)
that repeatedly calls the function f()
until f()
has raised n
ValueError
exceptions and then returns.
Do not count the times for which no exception, or a different exception, is raised by f()
For example, if the function onetry()
were defined as:
def onetry():
import random
if random.random() > 0.5:
print("raising ValueError")
raise ValueError
else:
raise NotImplementedError
Then rerun(onetry,5)
should result in "raising ValueError" always being printed 5 times.
You do not need to define the function f()
except for testing. The marking code will pass your rerun()
function a different function f()
.
def onetry():
import random
if random.random() > 0.5:
print("raising ValueError")
raise ValueError
else:
raise NotImplementedError
def rerun(f,n):
while n:
try:
f()
except ValueError:
n -= 1
except:
pass
return
rerun(onetry,5)
raising ValueError raising ValueError raising ValueError raising ValueError raising ValueError
# 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)
class newlist(list):
pop, copy = None, None
def __getitem__(self,i):
raise NotImplementedError("it's not a list!")
def q1():
assert len(builtins) == 4, f"builtins has {len(builtins)} elements"
hashvalues= (
'5fc7e38bffe00ca46add89145464a2eaf759d5c2',
'5039d155a71c0a5f7a2b2654ad49cb7ee47a8980',
'52018ef6a64fdefbf8127ede4f29a9094de1c755',
'87ea5dfc8b8e384d848979496e706390b497e547')
import hashlib
names=[]
for f in builtins:
try:
names.append(f.__name__)
except:
names.append("???")
for i,s in enumerate(names):
h = hashlib.sha1()
h.update(bytes(s,'utf-8'))
# print(s,h.hexdigest())
assert h.hexdigest() == hashvalues[i], \
f"builtins[{i}] ({s}) is not right"
def q2():
l = []
ni,ns,nw = [randint(0,3) for i in range(3)]
nt = [ni,ns,nw]
l.extend([1]*ni + [0]*randint(0,3))
l.extend([{1}]*ns + [{}]*randint(0,3))
l.extend(randwords(nw) + ['']*randint(0,3))
random.shuffle(l)
l = newlist(l)
ol = copy.deepcopy(l)
r = counttrue(l)
assert r == sum(nt), f"counttrue({ol}) returned {r}"
def q3():
nl = randint(3,5)
c = newlist((chr(randint(ord('a'),ord('z'))) for i in range(nl)))
n = newlist([randint(0,4) for i in range(nl)])
l=copy.deepcopy([n,c])
r = nrep(*l)
assert len(r) == nl and \
all([((set(rs)==set(c) or not n) and len(rs)==n) for rs,n,c in zip(r,n,c)]), \
f"nrep({n},{c}) returns {r}"
def q4():
for i in range(40):
c = complex(random.random(),random.random())
try:
stable(c)
except ValueError:
assert c.__abs__()>1,f"stable({c:.3f}) did not raise ValueError"
continue
except Exception as e:
assert False,f"stable(c) raised exception {e}"
continue
assert c.__abs__()<1,f"stable({c:.3f}) did not raise exception"
def q5():
n=randint(3,8)
m=0
def f():
nonlocal m
i = randint(1,3)
if i == 1:
m += 1
raise ValueError
elif i == 2:
raise RuntimeWarning
rerun(f,n)
assert m == n,f"rerun(f,{n}) asserted ValueError {m} times."
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.