How to open a file only for appending in python 3 - python-3.x

I want a try/except clause to take different actions if a file has not yet been created, versus if something's going to be appended to it. I've tried writing the following code:
try:
print("Appended!")
dip_line = "|".join(DATA)
dip_line = "|" + dip_line + "\n"
with open(OUTPUT_LOCATION, "a") as filey: # also tried "a+", no luck
filey.write(dip_line)
except:
print("Created!")
DATA.insert(0, SYS_COMMENT)
dip_line = "|".join(DATA)
dip_line += "\n"
with open(OUTPUT_LOCATION, "w") as filey:
filey.write(dip_line)
How can I ensure that the except clause gets run when no [OUTPUT_LOCATION] exists? Thanks for your consideration!

You can open the file in r+ (read-write) mode instead so it would raise an exception if the file does not already exist, and then use the seek method to point the file position to the end of the file for appending:
with open(OUTPUT_LOCATION, "r+") as filey:
filey.seek(0, 2)
filey.write(dip_line)

Related

Updating values in an external file only works if I restart the shell window

Hi there and thank you in advance for your response! I'm very new to python so please keep that in mind as you read through this, thanks!
So I've been working on some code for a very basic game using python (just for practice) I've written out a function that opens another file, selects a variable from it and adjusts that variable by an amount or if it's a string changes it into another string, the funtion looks like this.
def ovr(file, target, change):
with open(file, "r+") as open_file:
opened = open_file.readlines()
open_file.close()
with open(file, "w+") as open_file:
position = []
for appended_list, element in enumerate(opened):
if target in element:
position.append(appended_list)
if type(change) == int:
opened[position[0]] = (str(target)) + (" = ") + (str(change)) + (str("\n"))
open_file.writelines(opened)
open_file.close()
else:
opened[position[0]] = (str(target)) + (" = ") + ("'") + (str(change)) + ("'") + (str("\n"))
open_file.writelines(opened)
open_file.close()
for loop in range(5):
ovr(file = "test.py", target = "gold", change = gold + 1)
At the end I have basic loop that should re-write my file 5 times, each time increasing the amount of gold by 1. If I write this ovr() funtion outside of the loop and just run the program over and over it works just fine increasing the number in the external file by 1 each time.
Edit: I should mention that as it stands if I run this loop the value of gold increases by 1. if I close the shell and rerun the loop it increases by 1 again becoming 2. If I change the loop to happen any number of times it only ever increases the value of gold by 1.
Edit 2: I found a truly horrific way of fixing this isssue, if anyone has a better way for the love of god please let me know, code below.
for loop in range(3):
ovr(file = "test.py", target = "gold", change = test.gold + 1)
reload(test)
sleep(1)
print(test.gold)
The sleep part is because it takes longer to rewrite the file then it does to run the full loop.
you can go for a workaround and write your new inforamtion into a file called: file1
So you can use ur working loop outside of the write file. Anfter using your Loop you can just change the content of your file by the following steps.
This is how you dont need to rewrite your loop and still can change your file content.
first step:
with open('file.text', 'r') as input_file, open('file1.txt', 'w') as output_file:
for line in input_file:
output_file.write(line)
second step:
with open('file1.tex', 'r') as input_file, open('file.tex', 'w') as output_file:
for line in input_file:
if line.strip() == '(text'+(string of old value of variable)+'text)':
output_file.write('text'+(string of new value of variable)+' ')
else:
output_file.write(line)
then you have updated your text file.

Python 3.7.0 on Windows 10 unexpected behavior with open()

I'm new to Python and am seeing something unexpected based on other languages
I've worked with.
This code writes to a log file.
import datetime
import time
date = datetime.datetime.today().strftime('%Y-%m-%d')
mtime = time.strftime("%H:%M:%S")
myfile = "log_file." + date + ".txt"
# fh = open(myfile, "a") # Read program won't read new records if the open
# is done outside the loop
for x in range(100):
fh = open(myfile, "a") # Read program works as expected if this open
mtime = time.strftime("%H:%M:%S")
msg = str (mtime + " This is entry number " + str(x+1) + "\n")
fh.write(msg)
time.sleep( 2 )
fh.close
This code prints out new records written to the log file
import datetime
import time
date = datetime.datetime.today().strftime('%Y-%m-%d')
myfile = "log_file." + date + ".txt"
# This reads through all the records currently in the file.
lastLine = None
with open(myfile,'r') as f:
while True:
line = f.readline()
if not line:
break
# print(line)
lastLine = line
# This prints out all of the new lines that are added to the file.
while True:
with open(myfile,'r') as f:
lines = f.readlines()
if lines[-1] != lastLine:
lastLine = lines[-1]
print(lines[-1])
time.sleep(1)
If I place the open() in the write code before the for loop the read code never
sees the new records.
If I place the open() in the write code inside the loop the read code prints out
the new lines added to the file as expected. Is this correct behavior? If so, why?
The file is running in buffered mode. The reason that it works inside of the loop is that they file is being opened repeatedly and the buffer is likely flushed. If you need writes to the file to be visible quickly in the reader, then you can disable buffering when you open the file with the buffering=0 keyword argument. This should make the new lines visible quickly in the reader. You can also explicitly call f.flush() in the writer. See the docs on open() for more details.

Python - Spyder 3 - Open a list of .csv files and remove all double quotes in every file

I've read every thing I can find and tried about 20 examples from SO and google, and nothing seems to work.
This should be very simple, but I cannot get it to work. I just want to point to a folder, and replace every double quote in every file in the folder. That is it. (And I don't know Python well at all, hence my issues.) I have no doubt that some of the scripts I've tried to retask must work, but my lack of Python skill is getting in the way. This is as close as I've gotten, and I get errors. If I don't get errors it seems to do nothing. Thanks.
import glob
import csv
mypath = glob.glob('\\C:\\csv\\*.csv')
for fname in mypath:
with open(mypath, "r") as infile, open("output.csv", "w") as outfile:
reader = csv.reader(infile)
writer = csv.writer(outfile)
for row in reader:
writer.writerow(item.replace("""", "") for item in row)
You don't need to use csv-specific file opening and writing, I think that makes it more complex. How about this instead:
import os
mypath = r'\path\to\folder'
for file in os.listdir(mypath): # This will loop through every file in the folder
if '.csv' in file: # Check if it's a csv file
fpath = os.path.join(mypath, file)
fpath_out = fpath + '_output' # Create an output file with a similar name to the input file
with open(fpath) as infile
lines = infile.readlines() # Read all lines
with open(fpath_out, 'w') as outfile:
for line in lines: # One line at a time
outfile.write(line.replace('"', '')) # Remove each " and write the line
Let me know if this works, and respond with any error messages you may have.
I found the solution to this based on the original answer provided by u/Jeff. It was actually smart quotes (u'\u201d') to be exact, not straight quotes. That is why I could get nothing to work. That is a great way to spend like two days, now if you'll excuse me I have to go jump off the roof. But for posterity, here is what I used that worked. (And note - there is the left curving smart quote as well - that is u'\u201c'.
mypath = 'C:\\csv\\'
myoutputpath = 'C:\\csv\\output\\'
for file in os.listdir(mypath): # This will loop through every file in the folder
if '.csv' in file: # Check if it's a csv file
fpath = os.path.join(mypath, file)
fpath_out = os.path.join(myoutputpath, file) #+ '_output' # Create an output file with a similar name to the input file
with open(fpath) as infile:
lines = infile.readlines() # Read all lines
with open(fpath_out, 'w') as outfile:
for line in lines: # One line at a time
outfile.write(line.replace(u'\u201d', ''))# Remove each " and write the line
infile.close()
outfile.close()

F.write doesn't work

import os,sys
import time
from colorama import Fore,Back,Style,init
init(autoreset=True)
appdata_path = os.path.join(os.getenv("APPDATA"), os.pardir)
subpath = "Local/sieosp/filesav2292.sav"
f = open(os.path.join(appdata_path, subpath), "r+")
lines=f.readlines()
a1=int (lines[116])
a2=int (lines[120])
a3=int (lines[124])
b4=int (lines[128])
c5=int (lines[132])
d6=int (lines[136])
e7=int (lines[140])
d8=int (lines[144])
d9=int (lines[148])
d10=int (lines[152])
d11=int (lines[156])
d12=int (lines[160])
total=int (a1+a2+a3+b4+c5+d6+e7+d8+d9+d10+d11+d12)
if (total)==(12):
print("You already own every character")
else:
with f:
userinputvalue=int (input("Type 1 if you want to unlock every character,or 0 if you would like to close this \n"))
if(userinputvalue)==1:
lines[156]=f.write("1\n")
lines[116]=f.write("1\n")
lines[120]=f.write("1\n")
lines[124]=f.write("1\n")
lines[128]=f.write("1\n")
lines[132]=f.write("1\n")
lines[136]=f.write("1\n")
lines[140]=f.write("1\n")
lines[144]=f.write("1\n")
lines[148]=f.write("1\n")
lines[152]=f.write("1\n")
lines[160]=f.write("1\n")
else:
print("Closing")
time.sleep(1)
So this should work,right? Don't know why f.write doesn't write 1 to my file. am i using it very wrong? Searched around google for some more info but I didnt understand a thing :/ tried to use f.write as f.readlines but no luck. thanks
It looks like you dont open the file in write mode, only in read mode.
f = open(os.path.join(appdata_path, subpath), "r+")
Change the "r" to a "w"
You have opened the file with "r+", so the file is even writable, the problem is that if you open a file with "r+" you have to manage the pointer in the file, otherwise the string will be append at the end.
In order to manage it you have to use the function f.seek(offset, from_what) like described here Input and Output.
For example in this code I change only the first line of the file:
f = open("File/Path/file.txt", "r+")
f.seek(0,0)
f.write("something")
f.close()
You also use line[N] = f.write("something"), careful to use it in this way, because it returns the number of characters wrote, not the characters wrote ;)

Something's wrong with my Python code (complete beginner)

So I am completely new to Python and can't figure out what's wrong with my code.
I need to write a program that asks for the name of the existing text file and then of the other one, that doesn't necessarily need to exist. The task of the program is to take content of the first file, convert it to upper-case letters and paste to the second file. Then it should return the number of symbols used in the file(s).
The code is:
file1 = input("The name of the first text file: ")
file2 = input("The name of the second file: ")
f = open(file1)
file1content = f.read()
f.close
f2 = open(file2, "w")
file2content = f2.write(file1content.upper())
f2.close
print("There is ", len(str(file2content)), "symbols in the second file.")
I created two text files to check whether Python performs the operations correctly. Turns out the length of the file(s) is incorrect as there were 18 symbols in my file(s) and Python showed there were 2.
Could you please help me with this one?
Issues I see with your code:
close is a method, so you need to use the () operator otherwise f.close does not do what your think.
It is usually preferred in any case to use the with form of opening a file -- then it is close automatically at the end.
the write method does not return anything, so file2content = f2.write(file1content.upper()) is None
There is no reason the read the entire file contents in; just loop over each line if it is a text file.
(Not tested) but I would write your program like this:
file1 = input("The name of the first text file: ")
file2 = input("The name of the second file: ")
chars=0
with open(file1) as f, open(file2, 'w') as f2:
for line in f:
f2.write(line.upper())
chars+=len(line)
print("There are ", chars, "symbols in the second file.")
input() does not do what you expect, use raw_input() instead.

Resources