MBasith MBasith - 3 months ago 9
Python Question

Python Iterate over NoneType

I have the following code and am attempting to iterate over the results of each line and check if a calculated value in the 'untrained' dictionary is greater than 50%. However, some of the lines are NoneType and I am getting error: TypeError: 'NoneType' oject is not subscriptable. Is there a way I can ovoid this and still iterate to get my desired output below?

from collections import namedtuple
from itertools import zip_longest

trained = {'Dog': 4, 'Cat': 3, 'Bird': 1, 'Fish': 12, 'Mouse': 19, 'Frog': 6}
untrained = {'Cat': 6, 'Mouse': 7, 'Dog': 3, 'Wolf': 9}

Score = namedtuple('Score', ('total', 'percent', 'name'))

trained_scores = []
for t in trained:
trained_scores.append(
Score(total=trained[t],
percent=(trained[t]/(trained[t]+untrained.get(t, 0)))*100,
name=t)
)

untrained_scores = []
for t in untrained:
untrained_scores.append(
Score(total=untrained[t],
percent=(untrained[t]/(untrained[t]+trained.get(t, 0)))*100,
name=t)
)

# trained_scores.sort(reverse=True)
# untrained_scores.sort(reverse=True)

row_template = '{:<30} {:<30}'
item_template = '{0.name:<10} {0.total:>3} ({0.percent:>6.2f}%)'
print('='*85)
print(row_template.format('Trained', 'Untrained'))
print('='*85)

for trained, untrained in zip_longest(trained_scores, untrained_scores):
x = row_template.format(
'' if trained is None else item_template.format(trained),
'' if untrained is None else item_template.format(untrained)
)
print(x)


Current Output:

=====================================================================================
Trained Untrained
=====================================================================================
Mouse 19 ( 73.08%) Mouse 7 ( 26.92%)
Cat 3 ( 33.33%) Cat 6 ( 66.67%)
Frog 6 (100.00%) Wolf 9 (100.00%)
Dog 4 ( 57.14%) Dog 3 ( 42.86%)
Bird 1 (100.00%)
Fish 12 (100.00%)


Desired Output:

=====================================================================================
Trained Untrained
=====================================================================================
Mouse 19 ( 73.08%) Mouse 7 ( 26.92%)
Cat 3 ( 33.33%) Cat 6 ( 66.67%) <-- Above 50%
Frog 6 (100.00%) Wolf 9 (100.00%) <-- Above 50%
Dog 4 ( 57.14%) Dog 3 ( 42.86%)
Bird 1 (100.00%)
Fish 12 (100.00%)


Update!:

Updated with the suggested code that works. Thanks for all the help!

if untrained is not None and untrained[1] > 50:
print(x + '<-- Above 50%')
else:
print(x)


Result:

=====================================================================================
Trained Untrained
=====================================================================================
Mouse 19 ( 73.08%) Wolf 9 (100.00%) <-- Above 50%
Fish 12 (100.00%) Mouse 7 ( 26.92%)
Frog 6 (100.00%) Cat 6 ( 66.67%) <-- Above 50%
Dog 4 ( 57.14%) Dog 3 ( 42.86%)
Cat 3 ( 33.33%)
Bird 1 (100.00%)

Answer

You can not just skip the lines where untrained is None or you will skip the trained values, too. Instead, you should add an additional guard directly to the if condition checking whether the percentage is > 50:

if untrained is not None and untrained[1] > 50:
    print(x + '<-- Above 50%')
else:
    print(x)
Comments