Python notebook: Reading the note from a file - python

I am having trouble with one of my online coding exercises that I am trying to complete. The program does not read my note from the program as it should.
The exercise is simple, it wants me to add a code and then read it with time format and has other some menu options:
The last exercise in this chapter adds a small feature to the other continuous exercise project, the notebook. In this exercise, add a feature which includes the date and time of the written note to the program. The program works as earlier, but saves data in the form [note]:::[date and time] meaning that there is a three-colon separator between the note and timestamp. The timestamp can be generated as follows:
import time
time.strftime("%X %x")
'19:01:34 01/03/09'
This returns the date and time in a nice, compact string. When
working correctly, the program prints the following:
(1) Read the notebook.
(2) Add note.
(3) Empty the notebook.
(4) Quit
Please select one: 2.
Write a new note: Play football.
(1) Read the notebook.
(2) Add note.
(3) Empty the notebook.
(4) Quit.
Please select one: 1.
Play football:::21:11:24 11/04/11.
(1) Read the notebook.
(2) Add note.
(3) Empty the notebook.
(4) Quit.
Please select one: 4.
Notebook shutting down, thank you.
import time
try:
f=open("notebook.txt","r")
except Exception:
mf=open("notebook.txt","w")
mf="notebook.txt"
promptForNumbers = True
while True:
if promptForNumbers:
print("(1) Read the notebook\n(2) Add note\n(3) Empty the notebook\n(4) Quit\n")
selection=int(input("Please select one: "))
if selection==1:
handle = open(mf,"r")
filetext = handle.read()
print(filetext)
elif selection==2:
filetext=input("Write a new note: ")
myfile= open(mf, "w")
myfile.write(filetext)
myfile.write(":::")
myfile.write(time.strftime("%X %x"))
elif selection==3:
readfile = open(mf,"w")
readfile.close()
print("Notes deleted.")
elif selection == 4:
print("Notebook shutting down, thank you.")
break
else:
print("Incorrect selection")

You are missing myfile.close() after you finish writing to the file.
Ideally you should be closing the file after you finish operating on it (so it would be good to close handle.
Also, this might be bad formatting, but if your larger if is outside of while then you have to remove break in selection==4.

It looks like you are opening the file multiple times and not closing it, which could cause problems. Use with to handle files instead, as this will close the file automatically at the end of the block. Use try...except block to test whether the file exists at the point where the user tries to access it, rather than doing this at the start of the program.
import time
# Remove these lines which open the file without closing it (were you testing whether the file exists?)
#try:
# f=open("notebook.txt","r")
#
#except Exception:
# mf=open("notebook.txt","w")
mf="notebook.txt"
promptForNumbers = True
while True:
if promptForNumbers:
print("(1) Read the notebook\n(2) Add note\n(3) Empty the notebook\n(4) Quit\n")
selection=int(input("Please select one: "))
if selection==1:
try:
with open(mf) as f:
print(filetext.read())
except FileNotFoundError:
print("The notebook file was not found")
elif selection==2:
text = input("Write a new note: ")
with open(mf, "w") as f:
f.write(text)
f.write(":::")
f.write(time.strftime("%X %x"))
elif selection==3:
with open(mf, "w") as f:
pass
print("Notes deleted.")
elif selection == 4:
print("Notebook shutting down, thank you.")
break
else:
print("Incorrect selection")

The main problem is that you are not handling files the right way. They should not be opened at the start of the program and they have to be closed each time after use. Also, you need the "a" mode for appending. For starters, remove the try and except blocks, since they only cause problems and mf is overridden anyway.,
The next problem is the string argument that encodes the mode. If you want to read the file, you have to use "r", if you want to write something, you need "a" (or "r"). So if you want to be able to do both, you have to open the file each time the user chose an option. Finally, you have to close the file when you don't need it at the moment and that can be easily done by the with open([filename], [mode]) as file: term that automatically handles opening, closing and Errors in a save and readable way.
So for example:
if selection==1:
handle = open(mf,"r")
filetext = handle.read()
print(filetext)
should become:
if selection==1:
with open(mf, "r") as file:
filetext = file.read()
print(filetext)
That should solve every problem that is caused by interaction with files. though the rest of the code is rough on the eyes too and could use some refactoring (and should not be included in a StackOverflow question. Please try to provide minimal examples of your problem or question). Using f-Srings might be a nice way to get the task done in an easy and readably way.

change selection 1 to the following code. It Should work.
if selection==1:
with open(mf, "r") as f:
print(f.read())

From the first glance, your file handling is wrong.
try:
f=open("notebook.txt","r")
except Exception:
mf=open("notebook.txt","w")
This thing really confuses me about why it is there, as you never use f anywhere, do not close it and if it raises an error you are opening the file as mf but you immediately lose the reference to it as you assign a filename to mf.
You are opening the file multiple times, but rarely close it.
The preferred way of opening a file in Python is using context manager like so:
with open(mf, "w") as myfile:
myfile.write(filetext)
myfile.write(":::")
myfile.write(time.strftime("%X %x"))
This way when you exit the with block you are guaranteed to have your file closed.

Related

python script does not rewrite the file on itself

so first and foremost i wanted to connect multiple lines into one and add ","
so in example
line1
line2
line2
to
line1,line2,line3
i managed to make it work with this script right here
filelink = input("Enter link here ")
fix = file = open(filelink, "r")
data=open(filelink).readlines()
for n,line in enumerate(data):
if line.startswith("line"):
data[n] = "\n"+line.rstrip()
else:
data[n]=line.rstrip()
print(','.join(data))
HOWEVER in the terminal itself it shows it executed perfectly but in the text file itself it's still remains the same no connected lines and no commas
side note. i would love some explanations how does the loop work and what "enumerate" stands for and why specifically this code i tried googling each one separately and understand the code but i didn't manage to find what i was looking for if anyone keen to explain the code line by line shortly i would be very appreciative
Thanks in advance <3
This is somewhat superfluous:
fix = file = open(filelink, "r")
That's assigning two names to the same file object, and you don't even use fix, so at least drop that part.
For handling files, you would be better using a context manager. That means that you can open a resource and they will automatically get closed for you once you're done (usually).
In any case, you opened in read mode with open(filelink, "r") so you'll never change the file contents. print(','.join(data)) will probably show you what you expect, but print() writes to stdout and the change will only be in your terminal. You will not modify the base file with this. But, I think you're sufficiently close that I'll try close the missing connection.
In this case, you need to:
open the file first in read mode to pull the data out.
Do the transform in python to the data
Open the file again in write mode (which wipes the existing contents)
Write the transformed data
So, like this:
filelink = input("Enter link here ")
with open(filelink) as infile: # context manager, by default in "r" mode
data = [item.strip() for item in infile.readlines()]
data = ','.join(data)
# Now write it back out
with open(filelink, "w") as outfile:
outfile.write(data)

Python, repl.it - details are not being written to file using csv.writer and writer.writerow

I have the following repl.it program, and note that the registration part of the program, that was working fine before, has stopped working.
It gets to the end where it says "written to file" but somehow the actual write-rows command is being skipped as nothing is written to the text file.
The whole program is here:
https://repl.it/#oiuwdeoiuas/Matchmakingskills-1
The relevant part of the code is below, although there may be other factors (hence whole code provided)
def register():
print("===Register====")
print("First things first, sign up and tell us a little about yourself")
with open("dating.txt","a") as fo:
writer=csv.writer(fo)
firstname=input("Enter first name:")
lastname=input("Enter last name:")
username=firstname+lastname[0]+"bird"
print("Your automatically generated username is:",username)
password=input("Enter password:")
gender=input("Enter gender")
email=input("Enter email:")
dob=input("Enter date of birth in format dd/mm/yy:")
beliefs=input("Enter beliefs")
strengthslist=["patience","efficiency","sensitivity","frankness","submissiveness","leadership","timekeeping","laidback"]
print(strengthslist)
strengths=input("Enter your top strength: (select from the above list)")
contactcount=0
writer.writerow([username,password,firstname,lastname,gender,email,dob,beliefs,strengths,contactcount])
print("written to file")
mainmenu()
You're attempting to read a file that's still open:
def register():
# ...
with open("dating.txt","a") as fo:
# ...
print("written to file")
# At this point, "dating.txt" hasn't been written to
# the next call to open it that occurs here will
# see the state of the file either partially written, or before
# the row is written at all
mainmenu()
There are a few solutions. The quickest is to de-indent mainmenu() here one level:
def register():
# ...
with open("dating.txt","a") as fo:
# ...
print("written to file")
# dating.txt has been closed now, it's safe to read it
mainmenu()
When the next method comes along and tries to read the file, it will contain the expected data that way.
I may be wrong, but do you need writerows instead of writerow because writerows accepts a list just as yours and writerow accepts columns.
Like in this post

Reading a file, only if no other 'process' is working on it

I want to open 3 Powershell and run the same code at the 3 of them, just different files.
As they'll have exactly the same logic, each of them will try to access each other's files to check if there's anything written there
Process1 has client1.txt, Process2 has client2.txt and Process3 has client3.txt
Here's some code as to what process 3 should check before choosing which problem to work on:
import os
while True:
f = 'C:\Users\Files'
i = {}
i['word'] = 'problem X' #just an example, I'll have a whole list
if os.path.exists(f):
try:
os.rename(f, f)
print 'Access on file "' + f +'" is available!'
file1 = open('C:\Users\Files\client1.txt', 'r+')
file2 = open('C:\Users\Files\client2.txt', 'r+')
if file1.read() == i['word']:
print "A process is already working on this problem, check another"
elif file2.read() == i['word']:
print "A process is already working on this problem, check another"
else:
print "Found a new problem to work on"
file3 = open('C:\Users\Files\client3.txt', 'r+')
file3.write(i['word'])
file1.close()
file2.close()
file3.close()
except OSError as e:
print 'Access-error on file "' + f + '"! \n' + str(e)
time.sleep(5)
pass
What I tried to represent through the code is: I only want a process to start a problem if the others aren't working on it already, as they all have the same logic they'll try to solve the same problem (I have lots that need solving) and so they might reach at around the same time as the program goes on with the while True.
When it finishes the problem, it'll delete the contents of the file and pick a new problem, then write the problem it is working at in its own file for the others to check later.
Just to make it a bit clear: Let's say process1 found a problem to work first ('AAA'), they all have empty txt files, it'll check txt2 and txt3 and see it's not equal to ('AAA'), then it'll write it to its own file and close it.
I want process2 which might make it there a second later to read both txt1 and txt3 and see that ('AAA') is already being worked on, it'll get the next in the list and check again, seeing that ('BBB') is okay and it'll write on its own file.
When it ends, it deletes the String from the txt and starts looking for another one.
There's the problem of both process trying to check files at the same time too. Maybe if there's a way to put a time.sleep() to a process if another process is using the file and then try again a bit later?
Ideally you would use Python's multiprocessing module to start each process. You could have one process watch for new files and feed them to a queue that your worker processes read from. This solution would eliminate the need for any file locking since only one process is ever looking for new files.
If you must start the processes via Power Shell though, you'll have to use locking of some sort to get the processes working together. True file locking is difficult to do in a cross platform way. You can fake it by using move though. For instance, you could attempt to move the file (move is atomic on most operating system assuming you're moving to a location on the same filesystem). If the move fails, you know another process must have gotten to it first, or something went terribly wrong with the OS. You can then do all your processing on the moved file. For example:
import path
import shutil
filename = "C:\\path\\to\\filename.txt"
_filename = os.path.join(os.path.basename(filename), ".wip")
wip_filename = os.path.join(os.path.dirname(filename), _filename)
try:
shutil.move(filename, wip_filename)
except OSError:
# another process moved it first
pass
else:
do_work(wip_filename)

how do i get this program to write each line with a given word to a file?

i have everything working but the final step of having it write the lines to a file. any help would be awesome. i assume its either an issue with a function or a control structure thing.
def process(word, file_name, new_file_name):
'''Check the file for the word and returns lines with the word in it
'''
file=open(file_name, 'r')
file2=open(new_file_name, 'w')
for line in file:
if word in line:
file2.write(line)
else:
print("That word is not in this file.")
file.close()
print('File written')
def main():
global line
word=input('Enter a word: ').strip().lower()
file_name=input('Enter a file name: ')
new_file_name=input('Enter a new file name: ')
process(word, file_name, new_file_name)
main()
You forgot to close file2. Close that and it should be written out.
Also, a better way to open and close files is usually to use the with context manager:
with open(file_path, 'w') as my_f:
my_f.write('foo')
That will open and close on its own, closing outside of the with scope.
Also, it's more standard to write a main this way:
if __name__ == '__main__':
main()
# or just the main body here if it's simple enough
The reason for that is that you can import the file in other source code, and it won't execute main after it imports. You can write a module, import from it, or have test code in your main and then execute that directly to test it.
Also, what qwrrty said about your for else statement is correct. It will always print.
An else in a for or while loop is an interesting feature of Python that you won't see in many programming languages, for better or worse. It executes if the loop does not exit from a break statement. There is also a try except else that executes the else if the try block completes without any exception.
You should use an else for a situation like when you are iterating through a container, searching for an element, and want logic if you do not find it. If you find it, you are done, and you break. I don't see a good reason for an else in your example.
From briefly testing this code, it appears to work as intended, and writes to file2 all the lines from file that match word.
This code is printing a misleading message:
for line in file:
if word in line:
file2.write(line)
else:
print("That word is not in this file.")
The else clause to for is run when the iterator is exhausted, so this will always print "That word is not in this file." You want something more like this:
found = False
for line in file:
if word in line:
file2.write(line)
found = True
if not found:
print("That word is not in this file.")
As noted, it is also a good idea to make sure that you close file2 when you are done with it, and the with open(...) as file2 context manager is useful for that. But that should be causing the program to misbehave in this case.

Python - read and write input from user

I am having trouble writing this short program for my python class I was hoping someone could offer some assistance.
What I would like to accomplish:
1. Write a program that uses a while loop to accept input from the user (if the user presses Enter, exit the program).
2. Save the input to a file, then print it.
3. Upon starting, the program will display the current contents of the file.
Example:
Start program for first time.
Enter text: this is input
this is input.
Enter text: some more text
this is input. some more text.
When you start the program for a second time
this is input. some more text.
Enter text:
etc. etc.
What I have so far:
intext = open('user_input.txt','a')
intext.close()
string_input = input('Enter text: ')
while True:
open_input = open('user_input.txt','r')
if open_input:
for i in open_input:
print(i)
if string_input != "":
uinput = open('user_input.txt','a')
uinput.write(string_input + '.')
uinput.close()
rd = open('user_input.txt', 'r')
if rd:
for line in rd:
print(line)
if string_input == "":
t = open('user_input.txt', 'r')
for line in t:
print(line)
t.close()
break
Problems: Upon opening, any previously stored text does not display. If a user inputs text it prints in an infinite loop, and does not prompt to enter text again.
Positives: The input is recorded to the text file. If no text is entered, when exiting any previously entered text does display correctly.
Like I said, this is homework for me. I have searched for the answer, but I seem to be ripping the code apart and putting it back together only to get different errors. So some guidance on this would be greatly appreciated.
One thing I forgot to mention is that I am using Python 3.
Thanks again to David for helping me think more like a programmer. Here are the results:
intext = open('user_input.txt','r').readline()
print(intext)
while True:
string_input = input('Enter text: ')
if string_input == "":
t = open('user_input.txt', 'r').readline()
print(t)
break
if string_input != "":
d = open('user_input.txt', 'a')
d.write(string_input + '. ')
d.close()
n = open('user_input.txt', 'r').readline()
print(n)
I tried to keep the code as slim as possible, and it works now.
A couple questions additional questions that came out of this:
Do I need to close the file at the end? When I tried to close apnd and n , It gave me errors.
While looking for answers I came a across, this. Is it still best practice to use a "with" statement?
Example:
with open("x.txt") as f:
data = f.read()
do something with data
To be honest, your program as you've shown it is kind of a mess. I say this not to be insulting, but because you do have a pretty clear list of the steps your program needs to take, and I think you will wind up with a better understanding by scrapping your existing code and starting from scratch.
In your question, you listed the following steps:
Upon starting, display any previous content of the file
Use a while loop to
Accept input from the user
If the user presses Enter, exit the program
Save the input to a file
Print it (note: did you mean to print just the latest input, or everything in the file?)
Turning your overall task into a list of specific steps like this is probably 80% of the work of writing a computer program. All that's left to do is translate it into code. So I would suggest that you consider how to do each of these steps individually.
Write a code snippet to display the contents of a file
Write a code snippet to read a line of input from the user and store it in a variable
Write a code snippet to check the contents of a variable to see whether it's empty, and if so, exit
Write a code snippet to append the contents of a variable to a file
Write a code snippet to print the contents of a variable (or of a file, if that's what you meant to do)
Each of these can be done in one or two lines, so individually, you should have an easy time with them. Once you've done all the pieces, all you need to do is put them together:
# display the contents of the file
while True:
# read a line of input and store it in a variable
# check the contents of the variable to see if it's empty, and if so, exit
# append the contents of the variable to the file
# print the contents of the variable (or of the file)
Update: This is not a big deal, but you have an unnecessary if statement (the second one) in your revised program. Think about this: if string_input is empty, Python will execute the break statement, which terminates the loop immediately. So you'll only ever reach the second if statement if string_input is not empty. That means the condition string_input != "" is guaranteed to be true at that point in the program, and there's no need to check it.
Do I need to close the file at the end? When I tried to close apnd and n , It gave me errors.
Yes you do. Look at the pattern you used with d:
# open the file
d = open('user_input.txt', 'a')
# write to it (or read from it)
d.write(string_input + '. ')
# close it
d.close()
You should do the same thing every time you open a file, namely with intext, t, and n: open it, read from it, and then immediately close it.*
I'm guessing that the reason you encountered errors is that you tried to put the .close() statements at the end of the program, outside of the if statement and perhaps even outside of the while loop. That would give you a NameError because the variables n and t are not defined at those points in the program. They "expire" at the end of the block they are defined in. For more information on this, read up on scoping. (The Wikipedia article is probably not the best introduction, but you can search Stack Overflow and/or the web for more resources.)
While looking for answers I came a across, this. Is it still best practice to use a "with" statement?
Yes, the with statement is relatively new to Python and is the recommended way to do "quick" file I/O operations like this. Basically the with block takes care of closing the file at the end. For example, the code snippet above involving d is equivalent to
# open the file
with open('user_input.txt', 'a') as d:
# write to it (or read from it)
d.write(string_input + '. ')
# Python "automatically" closes it for you
*This "open-read/write-close" pattern of file access is usually a good idea. I've told you to use it in your program because it's important for you to learn how to split a program into small steps and convert each of the steps into code individually. But when you are writing a program that repeatedly writes things out to a file, or reads them in from a file, sometimes it is actually better to just open the file once in the beginning and just keep it open, rather than opening and closing it every time. If you are curious, one thing you could investigate is how to modify your program to reduce the number of times it has to open and close the file.
Use raw_input instead of input.
You forget to call input in the while loop
BTW, why not write data just at exit of the program instead of in each loop?

Categories