Python with statement issue - python

New to python and found one box still running very old code that doesn't support the with statement and admins not interested in upgrading as it will be replaced, but no ETA on replacement and need to get my script working
On another box with later version script works fine, but need to get it working on this older box
Extract from working script on later version
with open("ping.log","r") as reader:
while True:
line = reader.readline()
if len(line)==0:
break
status = line[34]
name = line[16:30]
if (status=="d"):
html+= '<tr>\n<td>\n<font color="red">'+ name+'</font><br>\n</td>\n</tr>\n'
else:
html+= '<tr>\n<td>\n<font color="green">'+ name+'</font><br>\n</td></tr>\n'
It basically opens file reads the contents and looks at specific position to see if device is up or down and make it red or green
Now I know you can use something like
fileh = open(file, 'w')
try:
# Do things with fileh here
finally:
fileh.close()
Need help with the part between try and finally

The as fileh part needs to be changed to an assignment to the file handle variable you want to use, reader, and that basically fixes it.
To wit,
reader = open("ping.log", 'r') # not 'w' if you are reading
try:
# Do things with reader here
# Basically copy-paste the stuff which was inside the with statement
finally:
reader.close()

You were actually on the right path:
fileh = open("ping.log", 'r') # you don't need the as reader part
try:
for line in fileh: # you can just iterate over the file, no need for while True
if len(line)==0:
break
status = line[34]
name = line[16:30]
if (status == "d"):
html+= '<tr>\n<td>\n<font color="red">'+ name+'</font><br>\n</td>\n</tr>\n'
else:
html+= '<tr>\n<td>\n<font color="green">'+ name+'</font><br>\n</td></tr>\n'
except:
print("ERROR")
finally:
fileh.close()
You could even make a variable color and set it depending on your status, so the lines are easier to change later like:
...
color = "red" if (status == "d") else "green"
html+= '<tr>\n<td>\n<font color="' + color + '">'+ name + '</font><br>\n</td>\n</tr>\n'
...
EDIT: As suggested, I updated for try, except, finally
EDIT 2:
For your second problem, as I understand it, you want to write or append to the file dash.aspx?
Then you wouldn't have to iterate over it
...
writer = open("dash.apsx", "w") #You need to check whether you want to use 'a' or 'w' for appending or writing
#no need to iterate over writerlines, you already have the file and can directly write to it
#INFO: this will put everything on one line, for new lines you could add "\n" e.g. writer.write(htmlBeg + "\n") etc.
writer.write(htmlBeg)
writer.write("<tr>")
writer.write(htmlTBeg)
writer.write('<th style="text-align:left"><h3>APAC Region Firewalls</h3></th>')
writer.write(html)
writer.write(htmlTEnd)
#close file at the end
write.close()
...

Related

How to add lines to file only if there aren't duplicates?

I have this code in Python which adds a line to a given file. The problem is that i want to add this blazegraph_address only if there isn't the same line already in the file. If there is, I don't need the address to be added to the file. The function code for this is below:
def write_to_address_file(blazegraph_address):
address_path = open("./saved_info/saved_address.txt", "a")
with open("./saved_info/saved_address.txt") as f:
seen = set()
seen.add(f.read())
print("SEEN",seen)
if blazegraph_address in seen:
print("ADDRESS IN SET ALREADY")
else:
seen.add(blazegraph_address)
address_path.write("\n"+str(blazegraph_address))
The problem is that the set populates with the file contents even though there are duplicates. How to only add to the file if the address is not in the file already?
Your code read the entire file, not line by line.
For this, you need to use create your set with the lines:
Modify:
seen = set()
seen.add(f.read())
With:
seen = set(f.read().split('\n'))
def write_to_address_file(blazegraph_address):
address_path = open("./saved_info/saved_address.txt", "a")
with open("./saved_info/saved_address.txt", "r") as msg:
data = msg.read().splitlines()
if blazegraph_address in data:
print("ADDRESS IN SET ALREADY")
else:
address_path.write("\n"+str(blazegraph_address))

How to automatically update a list of filenames in Python

I have a list of filenames: files = ["untitled.txt", "example.txt", "alphabet.txt"]
I also have a function to create a new file:
def create_file(file):
"""Creates a new file."""
with open(file, 'w') as nf:
is_first_line = True
while True:
line = input("Line? (Type 'q' to quit.) ")
if line == "q":
# Detects if the user wants to quuit.
time.sleep(5)
sys.exit()
else:
line = line + "\n"
if is_first_line == False:
nf.write(line)
else:
nf.write(line)
is_first_line = False
I want the list to update itself after the file is created. However, if I just filenames.append() it,
I realized that it would only update itself for the duration of the program. Does anybody know how to do this? Is this possible in Python?
"Is this possible in Python?" -> This has nothing to do with limitations of the language you chose to solve your problem. What you want here is persistence. You could just store the list of files in a text file. Instead of hardcoding the list in your code your program would then read the content every time it is run.
This code could get you started:
with open("files.txt") as infile:
files = [f.strip() for f in infile.readlines()]
print(f"files: {files}")
# here do some stuff and create file 'new_file'
new_file = 'a_new_file.txt'
files.append(new_file)
###
with open("files.txt", "w") as outfile:
outfile.write("\n".join(files))

Python code isnt printing contents of txt?

elif menuOption == "2":
with open("Hotel.txt", "a+") as file:
print (file.read())
Ive tried many different ways but my python file just refuses to print the txt contents. It is writing to the file but option 2 wont read it.
if menuOption == "1":
print("Please Type Your Guests Name.")
data1 = (input() + "\n")
for i in range (2,1000):
file = open("hotel.txt", "a")
file.write(data1)
print("Please Write your Guests Room")
data2 = (input("\n") + "\n")
file.write(data2)
data3 = random.randint(1, 999999)
file.write(str (data3))
print("Guest Added - Enjoy Your Stay.")
print("Guest Name is:", data1)
print("Guest Room Number Is:", data2)
print("Your Key Code Is:", data3)
I want all the above information to be added to a TXT. (That works) and then be able to read it also. which won't work.
Why and how can I fix?
You have to use r instead of a+ to read from file:
with open("Hotel.txt", "r") as file:
You are using a+ mode which is meant for appending to the file, you need to use r for reading.
Secondly I notice this
for i in range (2,1000):
file = open("hotel.txt", "a")
You are opening a new file handler for every iteration of the loop. Please open the file just once and then do whatever operations you need to like below.
with open("hotel.txt", "a") as fh:
do your processing here...
This has the added advantage automatically closing the file handler for you, otherwise you need to close the file handler yourself by using fh.close() which you are not doing in your code.
Also a slight variation to how you are using input, you don't need to print the message explicitly, you can do this with input like this.
name = input("Enter your name: ")

Issue with conditional statement on external python file

I created this script that could be used as a login, and then created an external text file that has the data 1234 in it, this is attempting to compare the data from the file, but outputs that the two values are different, even though they are the same. Thanks In advance to any help you can give me, the code I used is below:
getUsrName = input("Enter username: ")
file = open("documents/pytho/login/cdat.txt", "r")
lines = file.readlines()
recievedUsrName = lines[1]
file.close()
print(getUsrName)
print(recievedUsrName)
if recievedUsrName == getUsrName:
print("hello")
elif getUsrName != recievedUsrName:
print("bye")
else:
Try it like:
if recievedUsrName.strip() == getUsrName:
...
It must be the trailing newline.

File Operation in Python

What I am trying to do:
I am trying to use 'Open' in python and this is the script I am trying to execute. I am trying to give "restaurant name" as input and a file gets saved (reviews.txt).
Script: (in short, the script goes to a page and scrapes the reviews)
from bs4 import BeautifulSoup
from urllib import urlopen
queries = 0
while queries <201:
stringQ = str(queries)
page = urlopen('http://www.yelp.com/biz/madison-square-park-new-york?start=' + stringQ)
soup = BeautifulSoup(page)
reviews = soup.findAll('p', attrs={'itemprop':'description'})
authors = soup.findAll('span', attrs={'itemprop':'author'})
flag = True
indexOf = 1
for review in reviews:
dirtyEntry = str(review)
while dirtyEntry.index('<') != -1:
indexOf = dirtyEntry.index('<')
endOf = dirtyEntry.index('>')
if flag:
dirtyEntry = dirtyEntry[endOf+1:]
flag = False
else:
if(endOf+1 == len(dirtyEntry)):
cleanEntry = dirtyEntry[0:indexOf]
break
else:
dirtyEntry = dirtyEntry[0:indexOf]+dirtyEntry[endOf+1:]
f=open("reviews.txt", "a")
f.write(cleanEntry)
f.write("\n")
f.close
queries = queries + 40
Problem:
It's using append mode 'a' and according to documentation, 'w' is the write mode where it overwrites. When i change it to 'w' nothing happens.
f=open("reviews.txt", "w") #does not work!
Actual Question:
EDIT: Let me clear the confusion.
I just want ONE review.txt file with all the reviews. Everytime I run the script, I want the script to overwrite the existing review.txt with new reviews according to my input.
Thank you,
If I understand properly what behavior you want, then this should be the right code:
with open("reviews.txt", "w") as f:
for review in reviews:
dirtyEntry = str(review)
while dirtyEntry.index('<') != -1:
indexOf = dirtyEntry.index('<')
endOf = dirtyEntry.index('>')
if flag:
dirtyEntry = dirtyEntry[endOf+1:]
flag = False
else:
if(endOf+1 == len(dirtyEntry)):
cleanEntry = dirtyEntry[0:indexOf]
break
else:
dirtyEntry = dirtyEntry[0:indexOf]+dirtyEntry[endOf+1:]
f.write(cleanEntry)
f.write("\n")
This will open the file for writing only once and will write all the entries to it. Otherwise, if it's nested in for loop, the file is opened for each review and thus overwritten by the next review.
with statement ensures that when the program quits the block, the file will be closed. It also makes code easier to read.
I'd also suggest to avoid using brackets in if statement, so instead of
if(endOf+1 == len(dirtyEntry)):
it's better to use just
if endOf + 1 == len(dirtyEntry):
If you want to write every record to a different new file, you must name it differently, because this way you are always overwritting your old data with new data, and you are left only with the latest record.
You could increment your filename like this:
# at the beginning, above the loop:
i=1
f=open("reviews_{0}.txt".format(i), "a")
f.write(cleanEntry)
f.write("\n")
f.close
i+=1
UPDATE
According to your recent update, I see that this is not what you want. To achieve what you want, you just need to move f=open("reviews.txt", "w") and f.close() outside of the for loop. That way, you won't be opening it multiple times inside a loop, every time overwriting your previous entries:
f=open("reviews.txt", "w")
for review in reviews:
# ... other code here ... #
f.write(cleanEntry)
f.write("\n")
f.close()
But, I encourage you to use with open("reviews.txt", "w") as described in Alexey's answer.

Categories

Resources