Python KeyError if logic or try logic - python

I'm trying to loop through some JSON data to export to CSV and all is going well until I get to a portion of the data that I need to get certain field values where these fields do not always exist beneath "tags".
I'm getting the error of:
for alarm in tag["alarmst"]:
KeyError: 'alarmst'
I believe from Built-in Exceptions reading that this means the key/field just does not exist.
I read in Errors and Exceptions that I can put this logic in a try statement to say, if this key does not exist, don't give me the error and do something else or move onto the next set of records beneath "tag" where "alarmst" is and just dump that (and the other fields specified) to the file.
I'm having trouble figuring out how to tell this logic to stop giving me this error and to only use the csv_file.writerow() function with all the field values if only the "alarmst" exist.
Since I will be working with one file and processes before this Python process runs will get the "devs" and the "tags" to their own CSV files, I cannot parse the data and cut down on the for loops within the other for loops.
I'm not sure if the issue with the if tag["alarmst"] in tag: is due to there being so many for loops within others, or if I need to use a try statement somehow instead, or if I'm just not doing something else correctly since I'm new to Python at this level of coding but it seems to work for the need thus far.
I'm running this on Windows 10 OS if that makes any difference but I assume it doesn't.
Starting Code:
import json
import csv
with open('C:\\folder\\dev\\TagAlarms.txt',"r") as file:
data = json.load(file)
with open('C:\\folder\\dev\\TagAlarms.csv',"w",newline='') as file:
csv_file = csv.writer(file)
for dev in data["devs"]:
for tag in dev["tags"]:
for alarm in tag["alarmst"]:
csv_file.writerow(alarm['dateStatus'],[alarm['dateStart'], alarm['status'], alarm['type']])
If Code:
import json
import csv
with open('C:\\folder\\dev\\TagAlarms.txt',"r") as file:
data = json.load(file)
with open('C:\\folder\\dev\\TagAlarms.csv',"w",newline='') as file:
csv_file = csv.writer(file)
for dev in data["devs"]:
for tag in dev["tags"]:
for alarm in tag["alarmst"]:
if tag["alarmst"] in tag:
csv_file.writerow(alarm['dateStatus'],[alarm['dateStart'], alarm['status'], alarm['type']])

tag["alarmst"] is what throws the error. It means getting the value from tag associated with the key "alarmst" and there is no such key so it fails. if tag["alarmst"] in tag will throw the same error, and moreover you won't even reach that point if it's below for alarm in tag["alarmst"]:. What you want is:
if "alarmst" in tag:
for alarm in tag["alarmst"]:
But much nicer is:
for alarm in tag.get("alarmst", []):
get is similar to usual square bracket access but the second argument is a default if the key is not found. So if "alarmst" is not in the dictionary this will essentially be:
for alarm in []:
which is just an empty loop that won't run at all.

Related

Read csv file for datadriven testing in robotframework

I am currently trying to do some datadriven testing with robot framework from a csv file, using a python customlibrary. I am running in some problems though, would be grateful if someone can point me in the right direction
This is the error I am getting:
Resolving variable '${Tlogdata.0}' failed: SyntaxError: unexpected EOF while parsing (, line 1)
The csv I want to process currently has two records (I tried without, with single, and double codes):
1-KR8P27,11.0,1000
1-KR8P27,12.0,1001
I suspect the problem is with the customlibrary. I tried a lot in tweaking my code, but with what I found and my Python knowledge (that is admittably very basic) I cannot find any issue. This is what I currently have:
import csv
def read_csv_file(filename):
data = []
with open(filename,) as csvfile:
reader = csv.reader(csvfile)
for row in reader:
data.append(row)
return data
I am using some more keywords in Robot Framework to use this customlibrary to fetch data from my csv. While I suspect that my python code is the problem and I double checked everything I might be overlooking something here instead:
In a datamanager keyword file I created the following Keyword:
Get CSV Data
[Arguments] ${FilePath}
${Data} = read csv file ${FilePath}
[Return] ${Data}
Than I created a 'looping' keyword with a for loop:
Check multiple results
[Arguments] ${tlogdatas}
FOR ${tlogdata} IN ${tlogdatas}
Check result TLOG3 ${tlogdata}
The keyword I call in my loop is already used in a testcase without a datadriven setup, and works. Only the variables are named differently to make it work with the datadriven thing. The keyword looks like this:
Check result TLOG3
[Arguments] ${Tlogdata}
${queryResults} = query select x_ord_pts_earn, total_amt from siebel.s_order where
contact_id = ${Tlogdata.0} and total_amt = ${Tlogdata.1} and X_ORD_PTS_earn = ${Tlogdata.2}
# log #{queryResults[0][1]}
${dbvalue} = set variable ${queryResults}
${DB ordptsearn} = set variable ${queryResults[0][0]}
${DB contact_id} = set variable ${queryResults[0][1]}
should be equal as integers ${DB ordptsearn} ${Tlogdata.2}
should be equal as strings ${DB contact_id} ${Tlogdata.1}
END
Than in my testcase I define a variable which fetches its results from my datamanager keyword and use the looping keyword to go through the csv values:
Check TLOG results from CSVFile
${Tlogdata} = DataManager.Get CSV Data ${TLOG_RESULTS_CSVPath}
TLOG.Check multiple results ${Tlogdata}
It might also be worth it to show the values from the csv that are fetched according to the report file:
${Tlogdata} = [["'1-KR8P27'", "'11.0'", "'1000'"], ["'1-KR8P27'", "'12.0'", "'1001'"]]
I hope this is somewhat clear, I understand it is quit some text. But I am not 100% sure where the problem is in my scripts. I hope someone can point me in the right direction.
You are indexing your list wrong. Instead of ${Tlogdata.0} you should have ${Tlogdata[0]}, etc..
Here is a quick example:
*** Test Cases ***
Test
${Tlogdata}= Evaluate [["'1-KR8P27'", "'11.0'", "'1000'"], ["'1-KR8P27'", "'12.0'", "'1001'"]]
Log ${Tlogdata[0]}
Log ${Tlogdata[1]}
Log ${Tlogdata[0][1]}
Log ${Tlogdata[1][1]}

Iteration Error with TypeError: '_io.TextIOWrapper' object is not callable

QUESTION:
I am finding issues with the syntax of the code, in particular the for loop which i use to loop through the external file.
My program is a dice game which is supposed to register users, and the allow them to login to the game afterwards. In the end it must access the external file, which has previously been used to store the winner name (keep in mind the authorised names have a separate file), and loops through it and outputs the top 5 winners names and scores to the shell
I used a for loop to loop through the file and append it to an array called 'Top 5 Winners' however I seem to struggle with the syntax of the code as I am quite new Python.
The code that accesses the file.
with open("Top 5 Winners.txt","r") as db:
top5Winners=[]
for i in db(0,len([db])):
top5Winners.append(line)
top5Winners.sort()
top5Winners.reverse()
for i in range(5):
print(top5Winners[i])
Error Code:
for i in db(0,len([db])):
The len() part of the code is the issue
NOTE:
I also wouldn't mind any tips as to how i make this bit of code more efficient so i can apply it in my later projects.
Your indentation isn't as it should be. You indeed opened a file and made it readable, but after that you didn't do anything with it. See the following example:
with open(file, 'r') as db:
#code with file (db)
#rest of the code
So you can combine with your code like this:
top5winners = [] #Make a list variable
with open("Top 5 Winners.txt","r") as db: #Open your file
for i in db: #Loop trough contents of file
top5winners.append(i) #Append iterable to list
top5winners.sort(reverse=True) #Sort list and use reverse option
for i in range(0, 5): #Loop trough range
print(top5winners[i]) #Print items from list
Please note that StackOverflow is intended for help with specific cases, not a site to ask others to write a piece of code.
Sincerly, Chris Fowl.

Constant first row of a .csv file?

I have a Python code which is logging some data into a .csv file.
logging_file = 'test.csv'
dt = datetime.datetime.now()
f = open(logging_file, 'a')
f.write('\n "{:%H:%M:%S}",{},{}'.format(dt,x,y,))
The above code is the core part and this produces continuous data in .csv file as
"00:34:09" ,23.05,23.05
"00:36:09" ,24.05,24.05
"00:38:09" ,26.05,26.05
... etc.,
Now I wish to add the following lines in first row of this data. time, data1,data2.I expect output as
time, data1, data2
"00:34:09" ,23.05,23.05
"00:36:09" ,24.05,24.05
"00:38:09" ,26.05,26.05
... etc.,
I tried many ways. Those ways not produced me the result as preferred format.But I am unable to get my expected result.
Please help me to solve the problem.
I would recommend writing a class specifically for creating and managing logs.Have it initialize a file, on creation, with the expected first line (don't forget a \n character!), and keep track of any necessary information about that log(the name of the log it created, where it is, etc). You can then have the class 'write' to the log (append the log, really), you can create new logs as necessary, and, you can have it check for existing logs, and make decisions about either updating what is existing, or scrapping it and starting over.

Python JSON dictionary key error

I'm trying to collect data from a JSON file using python. I was able to access several chunks of text but when I get to the 3rd object in the JSON file I'm getting a key error. The first three lines work fine but the last line gives me a key error.
response = urllib.urlopen("http://asn.desire2learn.com/resources/D2740436.json")
data = json.loads(response.read())
title = data["http://asn.desire2learn.com/resources/D2740436"]["http://purl.org/dc/elements/1.1/title"][0]["value"]
description = data["http://asn.desire2learn.com/resources/D2740436"]["http://purl.org/dc/terms/description"][0]["value"]
topics = data["http://asn.desire2learn.com/resources/D2740436"]["http://purl.org/gem/qualifiers/hasChild"]
topicDesc = data["http://asn.desire2learn.com/resources/S2743916"]
Here is the JSON file I'm using. http://s3.amazonaws.com/asnstaticd2l/data/rdf/D2742493.json I went through all the braces and can't figure out why I'm getting this error. Anyone know why I might be getting this?
topics = data["http://asn.desire2learn.com/resources/D2740436"]["http://purl.org/gem/qualifiers/hasChild"]
I don't see this key "http://asn.desire2learn.com/resources/D2740436" anywhere in your source file. You didn't include your stack, but my first thought would be typo resulting in a bad key and you getting an error like:
KeyError: "http://asn.desire2learn.com/resources/D2740436"
Which means that value does not exist in the data you are referencing
The link in your code and your AWS link go to very different files. Open up the link in your code in a web browser, and you will find that it's much shorter than the file on AWS. It doesn't actually contain the key you're looking for.
You say that you are using the linked file, in which the key "http://asn.desire2learn.com/resources/S2743916" turns up once.
However, your code is downloading a different file - one in which the key does not appear.
Try using the file you linked in your code, and you should see the key will work.

Open URL stored in a csv file

I'm almost an absolute beginner in Python, but I am asked to manage some difficult task. I have read many tutorials and found some very useful tips on this website, but I think that this question was not asked until now, or at least in the way I tried it in the search engine.
I have managed to write some url in a csv file. Now I would like to write a script able to open this file, to open the urls, and write their content in a dictionary. But I have failed : my script can print these addresses, but cannot process the file.
Interestingly, my script dit not send the same error message each time. Here the last : req.timeout = timeout
AttributeError: 'list' object has no attribute 'timeout'
So I think my script faces several problems :
1- is my method to open url the right one ?
2 - and what is wrong in the way I build the dictionnary ?
Here is my attempt below. Thanks in advance to those who would help me !
import csv
import urllib
dict = {}
test = csv.reader(open("read.csv","rb"))
for z in test:
sock = urllib.urlopen(z)
source = sock.read()
dict[z] = source
sock.close()
print dict
First thing, don't shadow built-ins. Rename your dictionary to something else as dict is used to create new dictionaries.
Secondly, the csv reader creates a list per line that would contain all the columns. Either reference the column explicitly by urllib.urlopen(z[0]) # First column in the line or open the file with a normal open() and iterate through it.
Apart from that, it works for me.

Categories

Resources