Python Reading numbers from text file - python

I know this is a simple question, but I am extremely stuck.
file=open("record.txt","w+")
record = file.read()
print("The record is "+str(record)+"!!")
main code...
file.write(str(reaction))
file.close()
I have got his code and I've got a number of 0.433534145355 in the file, but when I do the command of print the +str(record)+, it only comes up with The record is !! and the number is not there. What is wrong with this code. Is there a special code with decimal places, and I do not want to use int().

As it says here:
'w+' Open for reading and writing. The file is created if it does not
exist, otherwise it is truncated. The stream is positioned at
the beginning of the file.
so yes, your file is also opened for reading, but it is truncated (i.e. it is now zero bytes long, it's empty), leaving nothing left to read of what was there already.
Essentially, the w in 'w+' means the mode is orientated to writing, giving you the option to read as well (useful in those cases when you need to seek back and read what you have written. There will be nothing to read unless you write)
Instead you can use:
'r+' Open for reading and writing. The stream is positioned at the
beginning of the file.
In this case, the r in 'r+' signifies the mode is orientated to reading, giving you the option to seek and write where necessary (useful when data is present already, but might need to be changed)

If you want to read from a file, you have to open it for reading too (r).

Related

how to write to a specific part of file?

i want replace a specific part of file by bytes, here's an ugly image to explain what i want to achieve:-
i tried to do it with this code
f=open('a.txt')
f.seek(250, os.SEEK_SET)
print(f.read(750))
it works fine, but it only reads the file, not actually writes to the file.
i tried to use this code
f=open('a.txt')
f.seek(250, os.SEEK_SET)
print(f.write('data', 750))
but write only takes 1 argument, so i can't use write command.
are there any methods i can achieve this in python?
Open the file in the appropriate mode, seek the position you want and write the amount of bytes you want to replace. To replace everything from position 250 to 750, you need to write 500 bytes.
Bytes isn't really correct in this case though, because it seems to be a text file and it is opened in text mode. Use "r+b" if you really wanted binary mode.
with open("a.txt", "r+") as f:
f.seek(250)
print(f.read(500))
f.seek(250)
f.write("X"*500)
You should use open('a.txt', 'r+'), the first answer to this question How to open a file for both reading and writing? has a good set up.

Opening, edit/rewrite string, save back to a new or same file

I want to open a file, decode the format of data (from base64 to ASCII), rewrite or save the decoded string, either back to the same file, or new one.
I have it opening, reading, decoding (and printing as a test) the decoded base64 string into readable format (ASCII I believe)
My goal is to now save this output to: either a "newfile.txt" document or back to the original "test.mcz" file ready for the next steps of my mission...
I know there are great online base64 decoders and they do work well for what I am doing - I use them often, but my goal is to write my own program as a learning exercise more than anything (also when my internet plays up I need an offline program)
Here's where I am so far (the original file is .mcz format it is a game save)
# PYTHON 3
import base64
f = open('test.mcz', 'r')
f_read = f.read()
# print(f_read) # was just as a test
new_f_read = base64.b64decode(f_read)
print (new_f_read)
This prints a butt-load of readable code that is what I need, but I don't want to have to just copy and paste this output from the Python shell into another editor, I want to save it to a file...for convenience.
Either back into the same test.mcz (I will be re-encoding to base64 again later on anyway) or to a new file - thus leaving my original as it was.
problem arises when I want to save/write this decoded output that is stored within the new_f_read variable...it's just been a headache, before I started I could visualise how it needed to be written, I got tripped up when I had to switch it all over to Python3 for some reason (Don't ask...) and I have tried so many variations from online examples - I wouldn't know where to start explaining what I've tried so far. I can't open the original file as both "r" AND "w" together so once Ive opened and decoded I cant reopen the original file as "w" because it just wipes the contents (which are still encoded anyway) -
I think I need to write functions to handle:
1. Open, read, save string to a variable
2. Manipulate string - decode
3. Write the new string to new or existing file
Sounds easy I know, but I am stuck...so here I am. If anyone shows examples, please take the time to explain what is going on, it seems pointless to me having code I don't understand. Apologies if this seems like a simple thing, help would be appreciated..Thanks
First, you can absolutely open a file for both reading and writing without truncating the contents. That's what the r+ mode is for (see https://docs.python.org/3/library/functions.html#open). If you do this, the model is (a) open the file, (b) read it, (c) seek back to the beginning with e.g. f.seek(0), (d) write it.
Secondly, you can simply open the file, read it, then close the file, and then reopen it, write it, and close it again, like this:
# open the file for reading, read the data, then close the file
with open('test.mcz', 'rb') as f:
f_read = f.read()
new_f_read = base64.b64decode(f_read)
# open the file for writing, write the data, then close the file
with open('test.mcz', 'wb') as f:
f.write(new_f_read)
This is probably the easiest solution.
The easiest thing is to open first a read file handle, close it then open a write handle. Read/Write handles are complicated because they have to have a pointer to where in the file you are and it add overhead that you don't need to use. You could do it if you wanted, but its a waste of time here.
Using the with operator to open files is recommended since the file will automatically close when you leave the with block.
import base64
with open('test.mcz', 'r') as f:
encode = base64.b64decode(f.read())
with open('test.mcz', 'wb') as f:
f.write(encode)
This is the same as
import base64
f = open('test.mcz', 'r'):
encode = base64.b64decode(f.read())
f.close()
f = open('test.mcz', 'wb'):
f.write(encode)
f.close()

seek function doesn't work to update a file in a specific position - python

I'm actually working on a project to send file using UDP, and since this protocol is not reliable I added some information on each packet which is the index of the data. So I can write the received data in the correct order.
I have problems to write bytes in a specific position in a file
this is the part of my code that handle writing new data :
while i < packet_num:
buf,address = recieve_packet(s,data_size+10)
i += 1
if buf:
print(buf)
index = int(buf[0:10].decode())
data = buf[10:]
f.seek(seek_pointer + index*data_size,0)
f.write(data)
list_index.append(index)
in this case the seek function has no effect and the data is just appended to the file. I'm using "a+b" mode to open the file.
Quoting from tutorialspoint.com,
Note that if the file is opened for appending using either 'a' or 'a+', any seek() operations will be undone at the next write.
"a" mode write operations append to the end of the file. What seek does is it sets the write/read pointer to a specific location in the file.
Therefore, when a write is called, it will write to the end of file, regardless of the read/write pointer.
However, because you've opened the file in a+b, you would be able to seek to a specific location and read it.
If you open using 'append' mode, all writes go to the end of the file. If ypu are already keeping track of where received data, then opening in w+b mode is all you need to do.
wb creates (or empties) the file, and allows writing (in binary, rather than text mode). w+b Does the same, but allows reading as well. If you want to open an existing file without truncating it, mode r+b will allow both reading and writing, while preserving the existing data (again, the b is for binary mode, which I expect is correct for your uses).

Beginner: Python - iterating through rows of csv, append result

I'm trying to input data from a csv and run that through a simple function and return it to the same CSV but appended onto the end of the row.
I'm having a hard time understanding the difference between the various modes(r, r+, a+, etc).
I've read the documentation but as a beginner am not understanding quite what they mean and which one is the right for me to be using in this case.
def appendCurrentTime():
with open("file.csv", "??") as myfile: #Opens File
reader = csv.reader(myfile)
for row in reader: #Runs through each row
myfile.write(current_time(row[1])) #appends the time, pulling in row[1] into current_time
**Also posting code for the first time, sorry if it doesn't come through clearly.
Looking at your code, the main problem is that the CSV file is not a "database", so you can't modify a row in the middle without corrupting the next row.
So, open the source file in "rb" mode and destination file in "wb" mode, and AFTER you processed the whole file - delete original and rename new file to the original name.
And, description for the cases you specified:
"r" - open text file for reading, starting from the beginning.
"r+" - open text file for reading and writing, starting from the beginning.
"a+" - create file if not exists; then open as a text file for reading and writing, starting from the end of file, plus you can only write to the end of the file.
In short, "R" means Read, "W" write, "+" - "and other way around", "B" - binary, absense of "B" means text. "A" differs from "W" in that "W" clears the file contents when you call open.
IMHO you should probably open files in binary mode most of the time, even if they are logically "text", to prevent unintended conversions of special characters (especially important with Unicode). So, I would recommend "wb" to "write new file", "rb" to "read existing" and "ab" to "append to existing file" e.g. a log file.
For even more information, read the documentation for the POSIX fopen function - Python tries to adhere to its semantics as much as possible, even on Windows systems.
Since it is a CSV file and implied text, the "rU" flag would be appropriate. The r flag means read and U is universal line terminator mode. This way it won't matter if the file is using Windows, Mac or Unix line terminators.
Also take a look into the Sniffer provided by the CSV library. It will automatically detect most dialects for you and can be passed into the reader function.
http://docs.python.org/2/library/csv.html#csv.Sniffer

seek() function?

Please excuse my confusion here but I have read the documentation regarding the seek() function in python (after having to use it) and although it helped me I am still a bit confused on the actual meaning of what it does, any explanations are much appreciated, thank you.
Regarding seek() there's not too much to worry about.
First of all, it is useful when operating over an open file.
It's important to note that its syntax is as follows:
fp.seek(offset, from_what)
where fp is the file pointer you're working with; offset means how many positions you will move; from_what defines your point of reference:
0: means your reference point is the beginning of the file
1: means your reference point is the current file position
2: means your reference point is the end of the file
if omitted, from_what defaults to 0.
Never forget that when managing files, there'll always be a position inside that file where you are currently working on. When just open, that position is the beginning of the file, but as you work with it, you may advance.
seek will be useful to you when you need to walk along that open file, just as a path you are traveling into.
When you open a file, the system points to the beginning of the file. Any read or write you do will happen from the beginning. A seek() operation moves that pointer to some other part of the file so you can read or write at that place.
So, if you want to read the whole file but skip the first 20 bytes, open the file, seek(20) to move to where you want to start reading, then continue with reading the file.
Or say you want to read every 10th byte, you could write a loop that does seek(9, 1) (moves 9 bytes forward relative to the current positions), read(1) (reads one byte), repeat.
The seek function expect's an offset in bytes.
Ascii File Example:
So if you have a text file with the following content:
simple.txt
abc
You can jump 1 byte to skip over the first character as following:
fp = open('simple.txt', 'r')
fp.seek(1)
print fp.readline()
>>> bc
Binary file example gathering width :
fp = open('afile.png', 'rb')
fp.seek(16)
print 'width: {0}'.format(struct.unpack('>i', fp.read(4))[0])
print 'height: ', struct.unpack('>i', fp.read(4))[0]
Note: Once you call read you are changing the position of the
read-head, which act's like seek.
For strings, forget about using WHENCE: use f.seek(0) to position at beginning of file and f.seek(len(f)+1) to position at the end of file. Use open(file, "r+") to read/write anywhere in a file. If you use "a+" you'll only be able to write (append) at the end of the file regardless of where you position the cursor.

Categories