Writing multiple values in a text file using python - python

I want to write mulitiple values in a text file using python.
I wrote the following line in my code:
text_file.write("sA" + str(chart_count) + ".Name = " + str(State_name.groups())[2:-3] + "\n")
Note: State_name.groups() is a regex captured word. So it is captured as a tuple and to remove the ( ) brackets from the tuple I have used string slicing.
Now the output comes as:
sA0.Name = GLASS_OPEN
No problem here
But I want the output to be like this:
sA0.Name = 'GLASS_HATCH_OPENED_PROTECTION_FCT'
I want the variable value to be enclosed inside the single quotes.

Does this work for you?
text_file.write("sA" + str(chart_count) + ".Name = '" + str(State_name.groups())[2:-3] + "'\n")
# ^single quote here and here^

Related

How to add a Google formula containing commas and quotes to a CSV file?

I'm trying to output a CSV file from Python and make one of the entries a Google sheet formula:
This is what the formula var would look like:
strLink = "https://xxxxxxx.xxxxxx.com/Interact/Pages/Content/Document.aspx?id=" + strId + "&SearchId=0&utm_source=interact&utm_medium=general_search&utm_term=*"
strLinkCellFormula = "=HYPERLINK(\"" + strLink + "\", \"" + strTitle + "\")"
and then for each row of the CSV I have this:
strCSV = strCSV + strId + ", " + "\"" + strTitle + "\", " + strAuthor + ", " + strDate + ", " + strStatus + ", " + "\"" + strSection + "\", \"" + strLinkCellFormula +"\"\n"
Which doesn't quite work, the hyperlink formula for Google sheets is like so:
=HYPERLINK(url, title)
and I can't seem to get that comma escaped. So in my Sheet I am getting an additional column with the title in it and obviously the formula does not work. Any help would be appreciated.
Try using ; as the formula argument separator. It should work the same.
Instead of reinventing the wheel, you should write your CSV rows using the builtin csv.writer class. This takes care of escaping any commas and quotes in the data, so you don't need to build your own escape logic. This helps you avoid the mess of escaping in your strLinkCellFormula = ... and strCSV = strCSV + ... lines.
For example:
import csv
urls = ["https://google.com", "https://stackoverflow.com/", "https://www.python.org/"]
titles = ["Google", "Stack Overflow", "Python"]
with open("file.csv", "w") as fw:
writer = csv.writer(fw)
writer.writerow(["Company", "Website"])
for u, t in zip(urls, titles):
formula = f'=HYPERLINK("{u}", "Visit {t}")'
row = [t, formula]
writer.writerow(row)
Note that in the line formula = ... above, I used the f-string syntax to format the URL and title into the string. I also used apostrophes to define the string, since I knew that the string was going to contain quotation marks and I didn't want to bother escaping them.
This gives the following CSV:
Company,Website
Google,"=HYPERLINK(""https://google.com"", ""Visit Google"")"
Stack Overflow,"=HYPERLINK(""https://stackoverflow.com/"", ""Visit Stack Overflow"")"
Python,"=HYPERLINK(""https://www.python.org/"", ""Visit Python"")"
where the escaping of commas and quotes is already taken care of.
It is also read by Excel/GSheets correctly, since it conforms to the standard CSV format:
For your specific case, you'd write to your CSV file like so:
with open(filename, "w") as wf:
writer = csv.writer(wf)
writer.writerow(headers) # if necessary
for ...:
strLink = f"https://xxxxxxx.xxxxxx.com/Interact/Pages/Content/Document.aspx?id={strID}&SearchId=0&utm_source=interact&utm_medium=general_search&utm_term=*"
strLinkCellFormula = f'=HYPERLINK("{strLink}", "{strTitle}")'
row = [strId, strTitle, strAuthor, strDate, strStatus, strSection, strLinkCellFormula]
writer.writerow(row)

Format string output

With this python's code I may read all tickers in the tickers.txt file:
fh = open("tickers.txt")
tickers_list = fh.read()
print(tickers_list)
The output that I obtain is this:
A2A.MI, AMP.MI, ATL.MI, AZM.MI, BGN.MI, BMED.MI, BAMI.MI,
Neverthless, I'd like to obtain as ouput a ticker string exactly formatted in this manner:
["A2A.MI", "AMP.MI", "ATL.MI", "AZM.MI", ...]
Any idea?
Thanks in advance.
If you want the output to look in that format you want, you would need to do the following:
tickers_list= "A2A.MI, AMP.MI, ATL.MI, AZM.MI, BGN.MI, BMED.MI, BAMI.MI"
print("["+"".join(['"' + s + '",' for s in tickers_list.split(",")])[:-1]+"]")
With the output:
["A2A.MI"," AMP.MI"," ATL.MI"," AZM.MI"," BGN.MI"," BMED.MI"," BAMI.MI"]
Code explanation:
['"' + s + '",' for s in tickers_list.split(",")]
Creates a list of strings that contain each individual value, with the brackets as well as the comma.
"".join(...)[:-1]
Joins the list of strings into one string, removing the last character which is the extra comma
"["+..+"]"
adds the closing brackets
Another alternative is to simple use:
print(tickers_list.split(","))
However, the output will be slightly different as in:
['A2A.MI', ' AMP.MI', ' ATL.MI', ' AZM.MI', ' BGN.MI', ' BMED.MI', ' BAMI.MI']
Having ' instead of "
A solution for that however is this:
z = str(tickers_list.split(","))
z = z.replace("'",'"')
print(z)
Having the correct output, by replacing that character
you can to use Split function:
tickers_list = fh.read().split(',')

Python: find strings inside dynamic text and put another text in front of the line

I've tried to find / build a solution but It's too complicated for me at the moment. I have a text from SAP (stored in tkinter's scrooledtext.
session.findById("wnd[0]").sendVKey 4
session.findById("wnd[1]/tbar[0]/btn[17]").press
session.findById("wnd[1]/usr/tabsG_SELONETABSTRIP/tabpTAB001/ssubSUBSCR_PRESEL:SAPLSDH4:0220/sub:SAPLSDH4:0220/ctxtG_SELFLD_TAB-LOW[3,24]").setFocus
session.findById("wnd[1]").sendVKey 0
session.findById("wnd[1]/usr/lbl[1,1]").setFocus
session.findById("wnd[1]").sendVKey 33
I would like to find every line when .sendVKey occurs, and put newtext at start of the line (or above the line) - eg in example there are 3 lines:
Added new text before sendkey text occurs!
session.findById("wnd[0]").sendVKey 4
(...)
Added new text before sendkey text occurs!<\b>
session.findById("wnd[1]").sendVKey 0
(...)
Tried using re.sub, re.findall and replace, but I think this is not a good approach. My working code is below, but it is not dynamic (in .sendVkey method it can be different window (0, 1, 2, 3 etc) in ("wnd[1]"). Any hints / solutions? Please help :(
def multiple_replace(string, rep_dict):
pattern = re.compile("|".join([re.escape(k) for k in sorted(rep_dict, key=len, reverse=True)]), flags=re.DOTALL)
return pattern.sub(lambda x: rep_dict[x.group(0)], string)
date_div = RPAcode.get("1.0", tk.END)
delay_vba_function = " Added new text before sendkey text occurs"
"
replaced_text = multiple_replace(date_div, {'.sendVKey' : '\n' + delay_vba_function + '\n' + '.sendVKey', \
'session.findById("wnd[1]").sendVKey' : '\n' + delay_vba_function + '\n' + 'session.findById("wnd[1]").sendVKey', \
'session.findById("wnd[2]").sendVKey' : '\n' + delay_vba_function + '\n' + 'session.findById("wnd[2]").sendVKey', \
'session.findById("wnd[3]").sendVKey' : '\n' + delay_vba_function + '\n' + 'session.findById("wnd[3]").sendVKey'})
#print(replaced_text)
RPAcode.delete('0.0', tk.END) #Deletes previous data
RPAcode.insert(1.0, replaced_text)
The simplest way to check whether a substring is in a string is by using the in-operator (in Python3.5 at least). Consider the following:
text = 'session.findById("wnd[0]").sendVKey 4'
if '.sendVKey' in text:
text = '(...)' + text
text
If you run it in the terminal, the output is gonna be:
'(...)session.findById("wnd[0]").sendVKey 4'
So, as you can see, the script even adds already some text in front of the text line. If you don't say text = '(...)' + text, but text = '(...)\n' + text, the (...) would show up in a line above the actual text. If you put the above code sample into a for loop iterating through all text lines, I think that approach might solve your problem.
Edit:
You first have to split the text into lines before iterating through the lines. I guess that is precisely what you need:
text = """session.findById("wnd[0]").sendVKey 4
session.findById("wnd[1]/tbar[0]/btn[17]").press
session.findById("wnd[1]/usr/tabsG_SELONETABSTRIP/tabpTAB001/ssubSUBSCR_PRESEL:SAPLSDH4:0220
session.findById("wnd[1]").sendVKey 0
session.findById("wnd[1]/usr/lbl[1,1]").setFocus
session.findById("wnd[1]").sendVKey 33"""
query_text = ".sendVKey"
addition = "(...) "
def indicate_lines(text, query_text, indication):
result = ''
text = text.splitlines()
for line in text:
if query_text in line:
result = result + indication + line + "\n"
else:
result = result + line + "\n"
return result
result = indicate_lines(text, query_text, addition)
print(result)
The result is gonna be:
(...) session.findById("wnd[0]").sendVKey 4
session.findById("wnd[1]/tbar[0]/btn[17]").press
session.findById("wnd[1]/usr/tabsG_SELONETABSTRIP/tabpTAB001
/ssubSUBSCR_PRESEL:SAPLSDH4:0220
(...) session.findById("wnd[1]").sendVKey 0
session.findById("wnd[1]/usr/lbl[1,1]").setFocus
(...) session.findById("wnd[1]").sendVKey 33
Note that I would expect regex to perform faster in case you want to have a scalable solution (because for-loops are comparatively slow in Python). But for most medium sized applications that will do the job.

How to concatenate multiple variables?

I have three UV sensors - integers output; one BME280 - float output (temperature and pressure); and one GPS Module - float output.
I need to build a string in this form - #teamname;temperature;pressure;uv_1;uv_2;uv_3;gpscoordinates#
and send them via ser.write at least one time per second- I'm using APC220 Module
Is this the right (and fastest) way to do it?
textstr = str("#" + "teamname" + ";" + str(temperature) + ";" + str(pressure) + ";" + str(uv_1) + ";" + str(uv_2) + ";" + str(uv_3) + "#")
(...)
ser.write(('%s \n'%(textstr)).encode('utf-8'))
You may try something like this:
vars = [teamname, temperature, pressure, uv_1, uv_2, uv_3, gpscoordinates]
joined = ';'.join( map( str, vars ))
ser.write( '#%s# \n', joined )
If using python 3.6+ then you can do this instead
textstr = f"#teamname;{temperature};{pressure};{uv_1};{uv_2};{uv_3}# \n"
(...)
ser.write((textstr).encode('utf-8'))
If teamname and gpscoordinates are also variables then add them the same way
textstr = f"#{teamname};{temperature};{pressure};{uv_1};{uv_2};{uv_3};{gpscoordinates}# \n"
(...)
ser.write((textstr).encode('utf-8'))
For more info about string formatting
https://realpython.com/python-f-strings/
It might improve readability to use python's format:
textstr = "#teamname;{};{};{};{};gpscoordinates#".format(temperature, pressure, uv_1, uv_2, uv_3)
ser.write(('%s \n'%(textstr)).encode('utf-8'))
assuming gpscoordinates is text (it's not in your attempted code). If it's a variable, then replace the text with {} and add it as a param to format.

How to use PyParsing's QuotedString?

I'm trying to parse a string which contains several quoted values. Here is what I have so far:
from pyparsing import Word, Literal, printables
package_line = "package: name='com.sec.android.app.camera.shootingmode.dual' versionCode='6' versionName='1.003' platformBuildVersionName='5.0.1-1624448'"
package_name = Word(printables)("name")
versionCode = Word(printables)("versionCode")
versionName = Word(printables)("versionName")
platformBuildVersionName = Word(printables)("platformBuildVersionName")
expression = Literal("package:") + "name=" + package_name + "versionCode=" + versionCode \
+ "versionName=" + versionName + "platformBuildVersionName=" + platformBuildVersionName
tokens = expression.parseString(package_line)
print tokens['name']
print tokens['versionCode']
print tokens['versionName']
print tokens['platformBuildVersionName']
which prints
'com.sec.android.app.camera.shootingmode.dual'
'6'
'1.003'
'5.0.1-1624448'
Note that all the extracted tokens are contains within single quotes. I would like to remove these, and it seems like the QuotedString object is meant for this purpose. However, I'm having difficulty adapting this snippet to use QuotedStrings; in particular, their constructor doesn't seem to take printables.
How might I go about removing the single quotes?
Replacing the expressions with the following:
package_name = QuotedString(quoteChar="'")("name")
versionCode = QuotedString(quoteChar="'")("versionCode")
versionName = QuotedString(quoteChar="'")("versionName")
platformBuildVersionName = QuotedString(quoteChar="'")("platformBuildVersionName")
seems to work. Now the script prints the output
com.sec.android.app.camera.shootingmode.dual
6
1.003
5.0.1-1624448
without quotation marks.

Categories