Key Error Running Python Script (Using Atom) - python

I have never used python before. I'm following a short guide on how to use an API with Python. I'm using Atom text editor plus the Hydrogen module to run said code.
I am getting KeyError: '203' when I run the following segment.
champ_dict = {}
for key in static_champ_list['data']:
row = static_champ_list['data'][key]
champ_dict[row['key']] = row['id']
for row in participants:
print(str(row['champion']) + ' ' + champ_dict[str(row['champion'])])
row['championName'] = champ_dict[str(row['champion'])]
# print dataframe
df = pd.DataFrame(participants)
df
the error occurs on the following line
print(str(row['champion']) + ' ' + champ_dict[str(row['champion'])])
I get that it's lookup error but I'm lost as how to resolve it.
Here is the full version of my code
#Test Script for interacting with
#RIOT API
#Built from 'Towards Data Science' guide
#If you want to use Hydrogen, install
#the Hydrogen Package and run
# python3 -m pip install ipykernel
# python3 -m ipykernel install --user
#This might allow pandas, idk
#-------------------------------------------
#Get installed module for Python
import riotwatcher
#Import tools.
from riotwatcher import LolWatcher, ApiError
#Import pandas
import pandas as pd
# Global variables
# Get new API from
# https://developer.riotgames.com/
api_key = 'RGAPI-XXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'
watcher = LolWatcher(api_key)
my_region = 'euw1'
#Use 'watcher' to get basic stats
me = watcher.summoner.by_name(my_region, 'RGE lnspired')
print(me)
#Use 'watcher' to get ranked ranked stats
my_ranked_stats = watcher.league.by_summoner(my_region, me['id'])
print(my_ranked_stats)
# Setup retrieval of match info
my_matches = watcher.match.matchlist_by_account(my_region, me['accountId'])
# Fetch info about last match
last_match = my_matches['matches'][0]
match_detail = watcher.match.by_id(my_region, last_match['gameId'])
#Setup Data Frame to view some of this stuff
participants = []
for row in match_detail['participants']:
participants_row = {}
participants_row['champion'] = row['championId']
participants_row['spell1'] = row['spell1Id']
participants_row['spell2'] = row['spell2Id']
participants_row['win'] = row['stats']['win']
participants_row['kills'] = row['stats']['kills']
participants_row['deaths'] = row['stats']['deaths']
participants_row['assists'] = row['stats']['assists']
participants_row['totalDamageDealt'] = row['stats']['totalDamageDealt']
participants_row['goldEarned'] = row['stats']['goldEarned']
participants_row['champLevel'] = row['stats']['champLevel']
participants_row['totalMinionsKilled'] = row['stats']['totalMinionsKilled']
participants_row['item0'] = row['stats']['item0']
participants_row['item1'] = row['stats']['item1']
participants.append(participants_row)
df = pd.DataFrame(participants)
df
#So now we can look at what is referred
#to as 'Static Data'
# check league's latest version
latest = watcher.data_dragon.versions_for_region(my_region)['n']['champion']
# Lets get some champions static information
static_champ_list = watcher.data_dragon.champions(latest, False, 'en_US')
# champ static list data to dict for looking up
champ_dict = {}
for key in static_champ_list['data']:
row = static_champ_list['data'][key]
champ_dict[row['key']] = row['id']
for row in participants:
print(str(row['champion']) + ' ' + champ_dict[str(row['champion'])])
row['championName'] = champ_dict[str(row['champion'])]
# print dataframe
df = pd.DataFrame(participants)
df

In order to retrieve a value from a standard dictionary in python with a key, it must be a valid or else a KeyError will be raised. So your code is attempting to use the key '203' with the dictionary champ_dict, however '203' is not a valid key (hence the KeyError). To see which keys are currently present in the dict, you can call the dict.keys method on champ_dict. Example would be something like
>>> champ_dict = {'key1': 'val1', 'key2': 'val2', 'key3': 'val3'}
>>> champ_dict.keys()
dict_keys(['key1', 'key2', 'key3'])

Related

Can't make apache beam write outputs to bigquery when using DataflowRunner

I'm trying to understand why this pipeline writes no output to BigQuery.
What I'm trying to achieve is to calculate the USD index for the last 10 years, starting from different currency pairs observations.
All the data is in BigQuery and I need to organize it and sort it in a chronollogical way (if there is a better way to achieve this, I'm glad to read it because I think this might not be the optimal way to do this).
The idea behing the class Currencies() is to start grouping (and keep) the last observation of a currency pair (eg: EURUSD), update all currency pair values as they "arrive", sort them chronologically and finally get the open, high, low and close value of the USD index for that day.
This code works in my jupyter notebook and in cloud shell using DirectRunner, but when I use DataflowRunner it does not write any output. In order to see if I could figure it out, I tried to just create the data using beam.Create() and then write it to BigQuery (which it worked) and also just read something from BQ and write it on other table (also worked), so my best guess is that the problem is in the beam.CombineGlobally part, but I don't know what it is.
The code is as follows:
import logging
import collections
import apache_beam as beam
from datetime import datetime
SYMBOLS = ['usdjpy', 'usdcad', 'usdchf', 'eurusd', 'audusd', 'nzdusd', 'gbpusd']
TABLE_SCHEMA = "date:DATETIME,index:STRING,open:FLOAT,high:FLOAT,low:FLOAT,close:FLOAT"
class Currencies(beam.CombineFn):
def create_accumulator(self):
return {}
def add_input(self,accumulator,inputs):
logging.info(inputs)
date,currency,bid = inputs.values()
if '.' not in date:
date = date+'.0'
date = datetime.strptime(date,'%Y-%m-%dT%H:%M:%S.%f')
data = currency+':'+str(bid)
accumulator[date] = [data]
return accumulator
def merge_accumulators(self,accumulators):
merged = {}
for accum in accumulators:
ordered_data = collections.OrderedDict(sorted(accum.items()))
prev_date = None
for date,date_data in ordered_data.items():
if date not in merged:
merged[date] = {}
if prev_date is None:
prev_date = date
else:
prev_data = merged[prev_date]
merged[date].update(prev_data)
prev_date = date
for data in date_data:
currency,bid = data.split(':')
bid = float(bid)
currency = currency.lower()
merged[date].update({
currency:bid
})
return merged
def calculate_index_value(self,data):
return data['usdjpy']*data['usdcad']*data['usdchf']/(data['eurusd']*data['audusd']*data['nzdusd']*data['gbpusd'])
def extract_output(self,accumulator):
ordered = collections.OrderedDict(sorted(accumulator.items()))
index = {}
for dt,currencies in ordered.items():
if not all([symbol in currencies.keys() for symbol in SYMBOLS]):
continue
date = str(dt.date())
index_value = self.calculate_index_value(currencies)
if date not in index:
index[date] = {
'date':date,
'index':'usd',
'open':index_value,
'high':index_value,
'low':index_value,
'close':index_value
}
else:
max_value = max(index_value,index[date]['high'])
min_value = min(index_value,index[date]['low'])
close_value = index_value
index[date].update({
'high':max_value,
'low':min_value,
'close':close_value
})
return index
def main():
query = """
select date,currency,bid from data_table
where date(date) between '2022-01-13' and '2022-01-16'
and currency like ('%USD%')
"""
options = beam.options.pipeline_options.PipelineOptions(
temp_location = 'gs://PROJECT/temp',
project = 'PROJECT',
runner = 'DataflowRunner',
region = 'REGION',
num_workers = 1,
max_num_workers = 1,
machine_type = 'n1-standard-1',
save_main_session = True,
staging_location = 'gs://PROJECT/stag'
)
with beam.Pipeline(options = options) as pipeline:
inputs = (pipeline
| 'Read From BQ' >> beam.io.ReadFromBigQuery(query=query,use_standard_sql=True)
| 'Accumulate' >> beam.CombineGlobally(Currencies())
| 'Flat' >> beam.ParDo(lambda x: x.values())
| beam.io.Write(beam.io.WriteToBigQuery(
table = 'TABLE',
dataset = 'DATASET',
project = 'PROJECT',
schema = TABLE_SCHEMA))
)
if __name__ == '__main__':
logging.getLogger().setLevel(logging.INFO)
main()
They way I execute this is from shell, using python3 -m first_script (is this the way I should run this batch jobs?).
What I'm missing or doing wrong? This is my first attemp to use Dataflow, so i'm probably making several mistakes in the book.
For whom it may help: I faced a similar problem but I already used the same code for a different flow that had a pubsub as input where it worked flawless instead a file based input where it simply did not. After a lot of experimenting I found that in the options I changed the flag
options = PipelineOptions(streaming=True, ..
to
options = PipelineOptions(streaming=False,
as of course it is not a streaming source, it's a bounded source, a batch. After I set this flag to true I found my rows in the BigQuery table. After it had finished it even stopped the pipeline as it where a batch operation. Hope this helps

Error while creating person group person in microsoft cognitive face API

I have a code which uses older API. I don't know new API. Those who know help me with modifying the code.
import cognitive_face as CF
from global_variables import personGroupId
import sqlite3
Key = '###################'
CF.Key.set(Key)
BASE_URL = 'https://region.api.cognitive.microsoft.com/face/v1.0/'
CF.BaseUrl.set(BASE_URL)
if len(sys.argv) is not 1:
res = CF.person.create(personGroupId, str(sys.argv[1])) #error line
print(res)
extractId = str(sys.argv[1])[-2:]
connect = sqlite3.connect("studentdb")
cmd = "SELECT * FROM Students WHERE id = " + extractId
cursor = connect.execute(cmd)
isRecordExist = 0
for row in cursor:
isRecordExist = 1
if isRecordExist == 1:
connect.execute("UPDATE Students SET personID = ? WHERE ID = ?",(res['personId'], extractId))
connect.commit()
connect.close()
As you mentioned you are using older API. You are expected to use the new API. Refer this (official documentation) for installing the package and further reference.
PACKAGE:
pip install --upgrade azure-cognitiveservices-vision-face
Import the following libraries (excluding other basic libraries)
from azure.cognitiveservices.vision.face import FaceClient
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.vision.face.models import TrainingStatusType, Person, SnapshotObjectType, OperationStatusType
The updated API command is as follows:
res = face_client.person_group_person.create(person_group_id, str(sys.argv[1]))
In addition to what Soorya answered above, For those who want the sample code reference, you can see the latest API sample code from here
def build_person_group(client, person_group_id, pgp_name):
print('Create and build a person group...')
# Create empty Person Group. Person Group ID must be lower case, alphanumeric, and/or with '-', '_'.
print('Person group ID:', person_group_id)
client.person_group.create(person_group_id = person_group_id, name=person_group_id)

Selecting values from a JSON file in Python

I am getting JIRA data using the following python code,
how do I store the response for more than one key (my example shows only one KEY but in general I get lot of data) and print only the values corresponding to total,key, customfield_12830, summary
import requests
import json
import logging
import datetime
import base64
import urllib
serverURL = 'https://jira-stability-tools.company.com/jira'
user = 'username'
password = 'password'
query = 'project = PROJECTNAME AND "Build Info" ~ BUILDNAME AND assignee=ASSIGNEENAME'
jql = '/rest/api/2/search?jql=%s' % urllib.quote(query)
response = requests.get(serverURL + jql,verify=False,auth=(user, password))
print response.json()
response.json() OUTPUT:-
http://pastebin.com/h8R4QMgB
From the the link you pasted to pastebin and from the json that I saw, its a you issues as list containing key, fields(which holds custom fields), self, id, expand.
You can simply iterate through this response and extract values for keys you want. You can go like.
data = response.json()
issues = data.get('issues', list())
x = list()
for issue in issues:
temp = {
'key': issue['key'],
'customfield': issue['fields']['customfield_12830'],
'total': issue['fields']['progress']['total']
}
x.append(temp)
print(x)
x is list of dictionaries containing the data for fields you mentioned. Let me know if I have been unclear somewhere or what I have given is not what you are looking for.
PS: It is always advisable to use dict.get('keyname', None) to get values as you can always put a default value if key is not found. For this solution I didn't do it as I just wanted to provide approach.
Update: In the comments you(OP) mentioned that it gives attributerror.Try this code
data = response.json()
issues = data.get('issues', list())
x = list()
for issue in issues:
temp = dict()
key = issue.get('key', None)
if key:
temp['key'] = key
fields = issue.get('fields', None)
if fields:
customfield = fields.get('customfield_12830', None)
temp['customfield'] = customfield
progress = fields.get('progress', None)
if progress:
total = progress.get('total', None)
temp['total'] = total
x.append(temp)
print(x)

FBX SDK - Get the FbxNode from an ENodeId of a Character

Is it possible to get the associated FbxNode from the enum ENodeId ?
for example if i want to get the FbxNode from the Character::eLeftHand
I tried to use Character::GetCharacterLink(ENodeId, FbxCharacterLink)
then extracting the FbxNode from FbxCharacterLink simply by calling FbxCharacterLink::mNode
However this function returns for most ENodeIds False, so no FbxCharacterLink is created.
character = myScene.GetCharacter(0)
lefthand = character.eLeftHand
lefthand_node = FbxCharacterLink()
character.GetCharacterLink(lefthand, lefthand_node) # False
lefthand_node = lefthand_node.mNode
when I was scripting inside Motionbuilder using Python and Pyfbxsdk, it was very easy, no matter how the skeleton objects are named, I can get the FBXObject of it
m = character.GetModel(self.BodyNodeObject[o])
and BodyNodeObject is generated with
def BodyNodes(self):
for i in dir(FBBodyNodeId):
if i[0] == 'k':
try:
self.BodyNodeObject[BodyNodesId[i]] = getattr(FBBodyNodeId, i)
except:
pass
BodyNodesId is simply a dictionary
BodyNodesId = OrderedDict({
'kFBChestNodeId':'Spine1',
'kFBHeadNodeId':'Head',
'kFBHipsNodeId':'Hips',
'kFBLeftAnkleNodeId':'LeftFoot',
'kFBLeftCollarNodeId':'LeftShoulder',
'kFBLeftElbowNodeId':'LeftForeArm',
...
})
this worked for me
from fbx import *
for i in range(myscene.GetCharacterCount()):
character = myscene.GetCharacter(i)
node = character.eHips
link = FbxCharacterLink()
while (character.GetCharacterLink(node, link)):
print node, link.mNode.GetName()
node = character.ENodeId(int(node+1))

Using Keys as Variables in Python

There is probably a term for what I'm attempting to do, but it escapes me. I'm using peewee to set some values in a class, and want to iterate through a list of keys and values to generate the command to store the values.
Not all 'collections' contain each of the values within the class, so I want to just include the ones that are contained within my data set. This is how far I've made it:
for value in result['response']['docs']:
for keys in value:
print keys, value[keys] # keys are "identifier, title, language'
#for value in result['response']['docs']:
# collection = Collection(
# identifier = value['identifier'],
# title = value['title'],
# language = value['language'],
# mediatype = value['mediatype'],
# description = value['description'],
# subject = value['subject'],
# collection = value['collection'],
# avg_rating = value['avg_rating'],
# downloads = value['downloads'],
# num_reviews = value['num_reviews'],
# creator = value['creator'],
# format = value['format'],
# licenseurl = value['licenseurl'],
# publisher = value['publisher'],
# uploader = value['uploader'],
# source = value['source'],
# type = value['type'],
# volume = value['volume']
# )
# collection.save()
for value in result['response']['docs']:
Collection(**value).save()
See this question for an explanation on how **kwargs work.
Are you talking about how to find out whether a key is in a dict or not?
>>> somedict = {'firstname': 'Samuel', 'lastname': 'Sample'}
>>> if somedict.get('firstname'):
>>> print somedict['firstname']
Samuel
>>> print somedict.get('address', 'no address given'):
no address given
If there is a different problem you'd like to solve, please clarify your question.

Categories