Python Triple-quoted strings with variable - python

Trying to write to a file with variables, but that is returning error:
template = """1st header line
second header line
There are people in rooms
and the %s
"""
with open('test','w') as myfile:
myfile.write(template.format()) % (variable)

The .format method expects you to template the blanks to be filled in your string with the {}-style, not %s. It also expects the interpolated values to be given as its arguments.
template = """1st header line
second header line
There are people in rooms
and the {}
"""
myfile.write(template.format(variable))

The given string literal is printf-style string. Use str % arg:
with open('test', 'w') as myfile:
myfile.write(template % variable)
To use str.format, you should use placeholder {} or {0} instead of %s.

The Error
myfile.write(template.format()) returns nothing to which you are using % operator to concatenate
Minimal Edit
You can perfectly use %s .The problem is you mismatched parenthesis and the parenthesis i.e. ) should be after your variable as in myfile.write(template.format() % (variable)). But as template.format() is redundant, it can be ignored. Thus the correct way is
myfile.write(template % (variable))
Note:- Any string with an empty format() and no {} in the string returns the string itself

Related

Read text file to create list and then convert to dictionary python

I am reading text file using
source= open(curr_file,"r")
lines= source.readlines()
This converts every line in my text file to a list, but some items in my list are created with double quotes while some are created with single quotes like below.
['[INFO] Name: Xxxx, section: yyyy, time: 21.2, status: 0\n', "proof:proof1,table: db.table_name,columns:['column_1'],count:10,status:SUCCESS\n",'run time: 30 seconds\n']
The first item in list is created with single quotes, while the second is created with double quotes.
When trying to convert the above to dictionary
new_line= dict(x.split(":"),1) for x in line.split(","))
It gives me a value error
Value error: dictionary update sequence element has length 1; 2 is required
The above error is because it considers the entire string under double quotes as single value and it's not able to convert it to dictionary.
Is there a way to convert it to single quotes instead of double. I tried using replace, strip. But nothing helps.
Expected output:
{
Name:Xxxx,
section:yyyy,
time:21.2,
proof:proof1
table:db.table_name
status: success
}
The quotes has nothing to do with the error. The exterior quotes of each line are not part of the str object. They are only printed to you know it is a str. The single quotes are switched to double because the content has single quotes in it, then single quotes cannot be used to delimit the str. But again, that is only a change in what is printed not in what is stored in memory.
Try to do it in steps and print the intermediate objects you get to debug the program.
for x in line: #prints nicer than print(line)
print(x)
arg = [x.split(":",1) for x in line.split(",")]
for x in arg:
print(x)
new_line = dict(arg)
you should get printed tuples with two elements
for convert your one line(str) to dict, you can use dictionary comprehension:
new_line = dict(x.split(":",1) for x in line.split()

Print specified output in subrocess

I want to print specified output in subrocess
Here is my code:
from subprocess import check_output
output = check_output(['python3', 'code.py']).decode('ascii')
print(output)
The output is:
Tom
John
How can I print just Tom or just John instead of both of them?
I have tried print(output[0]) to print Tom but I get only T.
You have single string and you can use any string's function.
You can split it and create list with lines
lines = output.split('\n')
And then display only first line
print(lines[0])
Let's take a look on steps you've already done:
You call check_output() and it returns output in the form of bytes;
Then You call bytes.decode(), which returns str.
As a result you get multi-line string. You've tried to access to first line using index 0, but you got first char instead of first line. It happened, cause accessing to string by index will return you char from this index.
To get first line you should split lines of your multi-line string (convert str to list of str). There's built-in function str.splitlines() which does what you need.
So, to upgrade your code we need to add one more line before your print() statement:
output_lines = output.splitlines()
After that you can access to line by index:
print(output_lines[0])

replacing text in a file, Python

so this piece of code is meant to take a line from a file and replace the certain line from the string with a new word/number, but it doesn't seem to work :(
else:
with open('newfile', 'r+')as myfile:
x=input("what would you like to change: \nname \ncolour \nnumber \nenter option:")
if x == "name":
print("your current name is:")
test_lines = myfile.readlines()
print(test_lines[0])
y=input("change name to:")
content = (y)
myfile.write(str.replace((test_lines[0]), str(content)))
I get the error message TypeError: replace() takes at least 2 arguments (1 given), i don't know why (content) is not accepted as an argument. This also happens for the code below
if x == "number":
print ("your current fav. number is:")
test_lines = myfile.readlines()
print(test_lines[2])
number=(int(input("times fav number by a number to get your new number \ne.g 5*2 = 10 \nnew number:")))
result = (int(test_lines[2])*(number))
print (result)
myfile.write(str.replace((test_lines[2]), str(result)))
f=open('newfile', 'r')
print("now we will print the file:")
for line in f:
print (line)
f.close
replace is a function of a 'str' object.
Sounds like you want to do something like (this is a guess not knowing your inputs)
test_lines[0].replace(test_lines[0],str(content))
I'm not sure what you're attempting to accomplish with the logic in there. looks like you want to remove that line completely and replace it?
also i'm unsure what you are trying to do with
content = (y)
the output of input is a str (which is what you want)
EDIT:
In your specific case (replacing a whole line) i would suggest just reassigning that item in the list. e.g.
test_lines[0] = content
To overwrite the file you will have to truncate it to avoid any race conditions. So once you have made your changes in memory, you should seek to the beginning, and rewrite everything.
# Your logic for replacing the line or desired changes
myfile.seek(0)
for l in test_lines:
myfile.write("%s\n" % l)
myfile.truncate()
Try this:
test_lines = myfile.readlines()
print(test_lines[0])
y = input("change name to:")
content = str(y)
myfile.write(test_lines[0].replace(test_lines[0], content))
You have no object known purely as str. The method replace() must be called on a string object. You can call it on test_lines[0] which refers to a string object.
However, you may need to change your actual program flow. However, this should circumvent the error.
You need to call it as test_lines[0].replace(test_lines[0],str(content))
Calling help(str.replace) at the interpreter.
replace(...)
S.replace(old, new[, count]) -> str
Return a copy of S with all occurrences of substring
old replaced by new. If the optional argument count is
given, only the first count occurrences are replaced.
Couldn't find the docs.

PostgreSQL TypeError: not all arguments converted during string formatting

I am executing a query in psycopg2 linked up to a PostgreSQL database. Here is the code in question:
with open('dataFile.txt', 'r') as f:
lines = f.readlines()
newLines = [line[:-1] for line in lines]
curr=conn.cursor()
lineString = ','.join(newLines)
curr.execute("SELECT fields.fieldkey FROM fields LEFT JOIN zone ON zone.fieldkey=fields.fieldkey WHERE zone.zonekey = %s;", (newLines[0]))
rows = curr.fetchall()
There's no issue connecting to the DB, and the type of lines[0] is definitely string, I checked that. Is there something wrong in the syntax of my string formatting?
The error I get, to clarify is this:
TypeError: not all arguments converted during string formatting
There must be a comma after lines[0] to make that a tuple.
curr.execute("""
SELECT fields.fieldkey
FROM fields
LEFT JOIN zone ON zone.fieldkey=fields.fieldkey
WHERE zone.zonekey = %s;
""", (lines[0],))
Since the execute method is expecting a sequence (or a mapping) it iterates over the string you provided surrounded by parenthesis. So it is necessary to explicitly make that a tuple. The same result, with clearer code, can be had using the tuple function:
(tuple(lines[0]))

Python Error: TypeError: not all arguments converted during string formatting

First python script and I'm getting an error I can't seem to get around using a config file. The first part of the script takes user input and puts that into a mysql database with no problem..Then I get to the filesystem work and things go a bit pear shaped..I can get it to work without using the config file options but I'd like to keep it consistent and pull from that file:
vshare = str(raw_input('Share the user needs access to: '))
vrights = str(raw_input('Should this user be Read Only? (y/n): '))
f = open("%s/%s" % (config['vsftp']['user_dir'], (vusername), 'wr'))
#f = open("/etc/vsftpd_user_conf/%s" % (vusername) , 'wr' )
f.write("local_root=%s/%s" % (config['vsftp']['local_root_dir'], vshare))
if vrights.lower() in ['y', 'ye', 'yes']:
buffer = []
for line in f.readlines():
if 'write_enable=' in line:
buffer.append('write_enable=NO')
else:
buffer.append(line)
f.writelines(buffer)
f.close()
The error I'm getting is:
TypeError: not all arguments converted during string formatting
If I uncomment the commented line it works and makes it a bit further and errors out as well..But I'll deal with that once I get this hiccup sorted.
Your tuple is misshaped
f = open("%s/%s" % (config['vsftp']['user_dir'], (vusername), 'wr'))
Should be
f = open("%s/%s" % (config['vsftp']['user_dir'], (vusername)), 'wr')
The error is here:
open("%s/%s" % (config['vsftp']['user_dir'], (vusername), 'wr'))
You have three parameters, but only two %s in the string. You probably meant to say:
open("%s/%s" % (config['vsftp']['user_dir'], vusername), 'wr')
Although 'wr' is unclear, you probably mean w+ or r+.
http://docs.python.org/library/functions.html#open
f = open("%s/%s" % (config['vsftp']['user_dir'], (vusername), 'wr'))
You are passing three arguments (config['vsftp']['user_dir'], (vusername), 'wr') to a format string expecting two: "%s/%s". So the error is telling you that there is an argument to the format string that is not being used.
I think you have a wrong parenthesis, your line should be:
f = open("%s/%s" % (config['vsftp']['user_dir'], (vusername)), 'wr')
It looks like this line should be:
f = open("%s/%s" % (config['vsftp']['user_dir'], vusername), 'wr')
(I moved the closing parenthesis over.)

Categories