from collections.abc import Iterator
def normalise_defensive(numbers):
if isinstance(numbers, Iterator):
raise TypeError("Must supply a container")
total = sum(numbers)
result = []
for value in numbers:
percent = 100 * value / total
result.append(percent)
return result
# works on a list
numbers_list = [15, 35, 80]
numbers_percentage = normalise_defensive(numbers_list)
assert sum(numbers_percentage) == 100.0
print("Successfully normalised numbers list")
# works on our custom class
class ReadVisits:
def __init__(self, path):
self.path = path
def __iter__(self):
with open(self.path) as f:
for line in f:
yield int(line)
try:
# generate some fake data
path = "temp.txt"
with open(path, "w") as f:
f.writelines([f"{visit}\n" for visit in numbers_list])
it = ReadVisits(path)
percentages = normalise_defensive(it)
print(percentages)
assert sum(percentages) == 100.0
assert percentages == numbers_percentages
print("Successfully normalised ReadVisits object")
except Exception:
pass
finally:
if os.path.exists(path):
os.remove(path)
# fails on an iterator
numbers_iter = iter(numbers_list)
normalise_defensive(numbers_iter) # should raise an exception