Read csv file for datadriven testing in robotframework - python

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]}

Related

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 KeyError if logic or try logic

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.

From spreadsheet to dictionary in ipython/python & more?

I would like to be able to take data from a file (spreadsheet or other) and create a dictionary that I can then iterate over in a loop for the keys, and have corresponding values inserted in my command for each key. Sorry if that does not make much sense, I will explain in more detail below.
I have several samples that I am running through a bioinformatics pipeline and I am trying to automate the process. One of the steps is adding "read group" information to my files which is done with the following shell command:
picard-tools AddOrReplaceReadGroups I=input.bam O=output.bam RGID=IDXX
RGLB=LBXX RGPL=PLXX RGPU=PUXX RGSM=SMXX VALIDATION_STRINGENCY=SILENT
SORT_ORDER=coordinate CREATE_INDEX=true
For each sample ID there is a different RGID, RGLB, GRPL, RGPU, and RGSM (and different input files, but I already know how to call that info.) What I would like to do is have a loop that executes this command for each sample ID and have the corresponding RGLB, GRPL, RGPU, and RGSM inserted into the command. Is there an easy way to do this? I have been reading a bit and it seems like a dictionary is probably the way to go, but it is not clear to me how to generate the dictionary and call the independent values into my command.
This should be pretty easy, but how you do it depends on the format of your input file. You're going to want something basically like this:
import subprocess # This is how we're going to call the commands.
samples = {} # Empty dict
with open('inputfile','r') as f:
for line in f:
# Extract sampleID, other things depending on file format...
samples[sampleID] = [rgid, rglb, grpl, rgpu, rgsm] # Populate dict
for sampleID in samples:
rgid, rglb, grpl, rgpu, rgsm = samples[sampleID]
# Now you can run your commands using the subprocess module.
# Remember to add a change based on sampleID if e.g. the IO files differ.
subprocess.call(['picard-tools', 'AddOrReplaceReadGroups', 'I=input.bam',
'O=output.bam', 'RGID=%s' % rgid, 'RGLB=%s' % rglb, 'RGPL=%s' %rgpl,
'RGPU=%s' % rgpu, 'RGSM=%s' % rgsm, 'VALIDATION_STRINGENCY=SILENT',
'SORT_ORDER=coordinate', 'CREATE_INDEX=true'])

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