meraki-analytics / cassiopeia

An all-inclusive Python framework for the Riot Games League of Legends API. Cass focuses on making the data easy and fun to work with, while providing all the tools necessary to create a website or do data analysis.
MIT License
552 stars 135 forks source link

AttributeError: 'ParticipantStatsData' object has no attribute 'firstInhibitorAssist' #173

Closed wuzechen closed 6 years ago

wuzechen commented 6 years ago

I am working on Cass to collect matches data. when I download the data, I found a bug I can not deal with. Here is my code

new_match = Match(id=new_match_id, region=region)
red = new_match.red_team
for participant in red.participants:
    ...
    data["red_player_first_inhibitor_assist_" + role] = \
                    participant.stats.first_inhibitor_assist is not None and participant.stats.first_inhibitor_assist or False
    ...

It is perfect for some matches, but in the other matches, an error occurs.

Here is the error log

Traceback (most recent call last):
  File "/anaconda3/lib/python3.6/site-packages/cassiopeia/core/match.py", line 25, in wrapper
    return method(self, *args, **kwargs)
  File "/anaconda3/lib/python3.6/site-packages/cassiopeia/core/match.py", line 901, in first_inhibitor_assist
    return self._data[ParticipantStatsData].firstInhibitorAssist
AttributeError: 'ParticipantStatsData' object has no attribute 'firstInhibitorAssist'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/XX/Workspace/LOL_S8_analysis/data_collecter/data_collecter.py", line 296, in <module>
    collect_matches()
  File "/Users/XX/Workspace/LOL_S8_analysis/data_collecter/data_collecter.py", line 143, in collect_matches
    participant.stats.first_inhibitor_assist is not None and participant.stats.first_inhibitor_assist or False
  File "/anaconda3/lib/python3.6/site-packages/cassiopeia/core/match.py", line 44, in wrapper
    return method(self, *args, **kwargs)
  File "/anaconda3/lib/python3.6/site-packages/cassiopeia/core/match.py", line 901, in first_inhibitor_assist
    return self._data[ParticipantStatsData].firstInhibitorAssist
AttributeError: 'ParticipantStatsData' object has no attribute 'firstInhibitorAssist'

I have checked the None situation, but it seems not work.

Even in the same match, sometimes error, and sometimes worked properly.

jjmaldonis commented 6 years ago

My guess is that sometimes Riot doesn't return that value, and sometimes they do. Can you dig into this and figure out whether that is true, and if so, under what circumstances they do/don't return that value?

wuzechen commented 6 years ago

It seems like when I call the second player's match data, it back null data. Here is the call log.

Making call: https://cdn.rawgit.com/meraki-analytics/cassiopeia/232dd330/cassiopeia/patches.json
Making call: https://jp1.api.riotgames.com/lol/summoner/v3/summoners/by-name/\xe5\xa4\x9c\xe7\xa9\xba\xe3\x81\xae\xe4\xb8\x89\xe6\x97\xa5\xe6\x9c\x88
Making call: https://jp1.api.riotgames.com/lol/summoner/v3/summoners/6305998
Making call: https://jp1.api.riotgames.com/lol/match/v3/matchlists/by-account/200475696?beginTime=1510139040000&endTime=1510740240000&queue=420
Making call: https://jp1.api.riotgames.com/lol/match/v3/matchlists/by-account/200475696?beginTime=1510740240000&endTime=1511222400000&queue=420
Making call: https://ddragon.leagueoflegends.com/realms/jp.json
Making call: https://jp1.api.riotgames.com/lol/match/v3/matches/160920392
Making call: https://jp1.api.riotgames.com/lol/match/v3/matches/160860866
Making call: https://jp1.api.riotgames.com/lol/match/v3/matches/160755703
Making call: https://jp1.api.riotgames.com/lol/match/v3/matches/160773714
Making call: https://jp1.api.riotgames.com/lol/match/v3/matches/160879599
Making call: https://jp1.api.riotgames.com/lol/match/v3/matches/160774706
Making call: https://jp1.api.riotgames.com/lol/match/v3/matches/160829992
Making call: https://jp1.api.riotgames.com/lol/match/v3/matchlists/by-account/200453358?beginTime=1510139040000&endTime=1510740240000&queue=420
Making call: https://jp1.api.riotgames.com/lol/match/v3/matchlists/by-account/200453358?beginTime=1510740240000&endTime=1511222400000&queue=420
Making call: https://jp1.api.riotgames.com/lol/match/v3/matches/160764934
Traceback (most recent call last):
  File "C:\Users\xxx\Anaconda3\lib\site-packages\cassiopeia\core\match.py", line 25, in wrapper
    return method(self, *args, **kwargs)
  File "C:\Users\xxx\Anaconda3\lib\site-packages\cassiopeia\core\match.py", line 947, in first_inhibitor_assist
    return self._data[ParticipantStatsData].firstInhibitorAssist
AttributeError: 'ParticipantStatsData' object has no attribute 'firstInhibitorAssist'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "E:/LOL_S8_analysis/data_collecter/data_collecter.py", line 296, in <module>
    collect_matches()
  File "E:/LOL_S8_analysis/data_collecter/data_collecter.py", line 143, in collect_matches
    participant.stats.first_inhibitor_assist is not None and participant.stats.first_inhibitor_assist or False
  File "C:\Users\xxx\Anaconda3\lib\site-packages\cassiopeia\core\match.py", line 44, in wrapper
    return method(self, *args, **kwargs)
  File "C:\Users\xxx\Anaconda3\lib\site-packages\cassiopeia\core\match.py", line 947, in first_inhibitor_assist
    return self._data[ParticipantStatsData].firstInhibitorAssist
AttributeError: 'ParticipantStatsData' object has no attribute 'firstInhibitorAssist'

Is it better to sleep sometime before starting next iteration? I tried sleep 30s before starting new iteration, but it doesn't work.

jjmaldonis commented 6 years ago

It looks like, for some reason, Riot doesn't return firstInhibitorAssist at all for match 160793986, whereas the other matches do return firstInhibitorAssist.

One workaround is to to replace this line:

participant.stats.first_inhibitor_assist is not None and participant.stats.first_inhibitor_assist or False

with this line:

getattr(participant.stats, "first_inhibitor_assist", None)

where None means "we don't know, because Riot didn't give us that data".

Will that work for you?

wuzechen commented 6 years ago

It works well! Though sometimes riot returns a null value, the script can work without breaking. Thank you very much.