Why is the written python file 5120 bytes in size? - python

I wrote a python script with python3.4 and ran it on my chromebook with Tegra K1 processor.
Here is the code
def fib(n):
a, b = 1, 1
for i in range(n - 1):
a, b = b, a + b
return a
i = 2
while True:
n = fib(i)
with open('nums', 'w') as f:
f.write(str(n))
print(n)
i += 1
It was running for few minutes, and then I shut it down by Ctrl+C. After that, I checked the content of the written file called nums. but found out that only 1 was written into it but the file size was 5120 bytes.
Why was the file size 5120 bytes?

The loop logic seems incorrect: You are opening the file each time when you have merely one number to write. Here's the fixed version:
with open('nums', 'w') as f:
i = 2
while True:
n = fib(i)
f.write(str(n))
i += 1
Also, as you are halting the script by Ctrl+C, you may want to add another line of f.flush() after f.write, to make sure the change is flushed onto the disk.
EDITED:
Alternatively, as #tdelaney has mentioned in the comment (thank you #tdelaney :) ), you could use the append mode by simply replacing with open('nums', 'w') with with open('nums', 'wa'). However this approach:
Is of low efficiency: The file needs to be opened and closed once for each number while it's really unnecessary.
Does not handle the file well: Content of the file would not be cleared when the script starts. Thus when you invoke the script for multiple times, the file would contain results from previous runs.

Try doing the work inside the write loop
def fib()
with open("nums", "a") as f:
<bulk of code>
f.write(str(n))

The reason your file is big is because it keeps looping forever without stopping so when you terminate the program there are a lot of 0 bytes written there.
Here is a working solution with
def fib(n):
a, b = 1, 1
for i in range(n - 1):
a, b = b, a + b
return a
with open('nums', 'w') as f:
i = 1
while i <= 10:
n = fib(i)
f.write(str(n) + "\n")
i += 1

Related

Python, how can I set iterator of enumerate to 0 while reading same file again and again

with open("...txt") as fp:
for i, line in enumerate(fp):
if some condition :
i=0
fp.seek(0)
Text is huge, GBs of data so I use enumerate. I need to process this huge file several thousands of time so I decided to open it just at first time for efficiency. However although this code works, i does not become 0 and it just goes on incrementing. I need that to be zero because I need position of lines i. And it is just inefficient to multiply billions*several thousands everytime and make some modular arithmetic.
So my question is how can I set i to be zero when I go back to the beginning of file? Thanks in advance (I use python 3.6)
You could always make your own resettable enumerator, but there are probably better ways to do what you really want to do.
Still, here's what a resettable enumerator looks like:
def reset_enumerate(thing, start=0):
x = start
for t in thing:
val = yield t, x
if val is not None:
x = val
else:
x += 1
Then you would use it like this:
r = reset_enumerate(range(10))
for i, num in r:
print('i:', i, 'num:', num)
if i == 5:
i, num = r.send(0)
print('i:', i, 'num:', num)
As stated in the comment, enumerate is a generator function. It's "exhausted" by the time it completes. This is also why you can't just "reset" it. Here is the PEP on enumerate to further explain how it works.
Furthermore, as also indicated in the comments, this post provides the typical way to handle large files.
Here is an example of how you can emulate a scenario like yours:
Assuming i have a file called input.txt with this kind of data:
1
2
3
Code:
j = 0
with open('input.txt', 'r') as f:
for k in f:
# A break condition
# If not we'll face an infinite loop
if j > 4:
break
if k.strip() == '2':
f.seek(0)
print("Return to position 0")
# Don't forget to increment j
# Otherwise, we'll end up with an infinite loop
j += 1
print(k.strip())
Will output:
1
Return to position 0
2
1
Return to position 0
2
1
Return to position 0
2
1
Return to position 0
2
1
Return to position 0
2

Script returns "Killed"

I have this rather simple script which generates 1000000000 (nine zeroes) numbers and then store in a file the generated numbers a how many times they were generated.
import random
import csv
dic = {}
for i in range(0, 1000000000):
n = random.randint(0, 99999)
if n in dic:
dic[n] += 1
else:
dic[n] = 1
writer = csv.writer(open('output', 'w'))
for key, value in dic.iteritems():
writer.writerow([key, value])
writer.close()
The script is exiting with a Killed message. According to this question What does 'killed' mean?, using dic.iteritems() should be enough for preventing such issue, but that's not the case.
So how could I proceed to accomplish such task?
It doesn't look like your problem is the dict. Your problem is here:
for i in range(0, 1000000000):
^^^^^^^^^^^^^^^^^^^^
On Python 2, that's a list 1000000000 items long, more than your system can handle. You want xrange, not range. xrange generates numbers on demand. (On Python 3, range does what xrange used to and xrange is gone.)
Oh, and if you think 11 GB should be enough for that list: not in Python. Try sys.getsizeof(0) to see how many bytes an int takes.

Adding Loop in the File Command Python

ı wanna create a file which as :
X values:
1
2
3
4
5
.
.
.
999
to do that ı wrote that command but ;
error like :argument 1 must be string or read-only character buffer, not float,,
from numpy import *
c = open("text.txt","w")
count = 0
while (count < 100):
print count
count = count + 0.1
c.write (count)
c.close
When writing to a file, you must write strings but you are trying to write a floating point value. Use str() to turn those into strings for writing:
c.write(str(count))
Note that your c.close line does nothing, really. It refers to the .close() method on the file object but does not actually invoke it. Neither would you want to close the file during the loop. Instead, use the file as a context manager to close it automatically when you are d one. You also need to include newlines, explicitly, writing to a file does not include those like a print statement would:
with open("text.txt","w") as c:
count = 0
while count < 100:
print count
count += 0.1
c.write(str(count) + '\n')
Note that you are incrementing the counter by 0.1, not 1, so you are creating 10 times more entries than your question seems to suggest you want. If you really wanted to only write integers between 1 and 999, you may as well use a xrange() loop:
with open("text.txt","w") as c:
for count in xrange(1, 1000):
print count
c.write(str(count) + '\n')
also, you're closing your file on each iteration of the while loop, so this will write your first line and then crash.
Unindent your last line so that the file's only closed after everything's been written to it:
while (count < 100):
print count
count = count + 0.1
c.write(str(count))
c.close()
Multiple problems which I can see are :
1. You can only write character buffer to file. The solution to main question u asked.
c.write (count) should be c.write (str(count))
2. You need to close your file outside the loop. You need to unindent c.close
from numpy import *
c = open("text.txt","w")
count = 0
while (count < 100):
print count
count = count + 0.1
c.write (count)
c.close()
3. Even after these this code will print and save numbers incremented with 0.1 i.e 0.1,0.2,0.3....98.8,99.9 You can use xrange to solve your problem.
result='\n'.join([str(k) for k in xrange(1,1000)])
print result
c = open("text.txt","w")
c.write(result)
c.close()

while loop won't break,should break when the counter is no longer less than the length of the array

trying to compare items in a and b and return greatest number at each index in list big - result should be [9,14,9,14,15,18,15].doing this for a class, must use while loop and counter
a = [7,12,9,14,15,18,12]
b = [9,14,8,3,15,17,15]
big = []
i = 0
length = len(a)
while i < length:
if a[i] > b[i]:
big.append(a[i])
else:
big.append(b[i])
i = i + 1
print(big)
There is nothing wrong with the code. I just copied it and ran through the IDLE. Output is exactly as you specified
If you run your code directly in the python shell, you will get a SyntaxError.
For more info, see http://bugs.python.org/issue11433
If you save the code down in a file, say test.py, then run python test.py, it will print out the result as expected.
Edit:
This answer is currently having a -1 rating. Before you downvote, can you actually read and try to understand the answer?
This is what I am talking about:

Go to a specific line and read the next few in Python

I have this huge (61GB) FASTQ file of which I want to create a random subset, but which I cannot load into memory. The problem with FASTQs is that every four lines belong together, otherwise I would just create a list of random integers and only write the lines at these integers to my subset file.
So far, I have this:
import random
num = []
while len(num) < 50000000:
ran = random.randint(0,27000000)
if (ran%4 == 0) and (ran not in num):
num.append(ran)
num = sorted(num)
fastq = open("all.fastq", "r", 4)
subset = open("sub.fastq", "w")
for i,line in enumerate(fastq):
for ran in num:
if ran == i:
subset.append(line)
I have no idea how to reach the next three lines in the file before going to the next random integer. Can someone help me?
Iterate over the file in chunks of four lines.
Take a random sample from that iterator.
The idea is that you can sample from a generator without random access, by iterating through it and choosing (or not) each element in turn.
You could try this:
import random
num = sorted([random.randint(0,27000000/4)*4 for i in range(50000000/4)])
lines_to_write = 0
with open("all.fastq", "r") as fastq:
with open("sub.fastq", "w") as subset:
for i,line in enumerate(fastq):
if len(num)==0:
break
if i == num[0]:
num.pop(0)
lines_to_write = 4
if lines_to_write>0:
lines_to_write -= 1
subset.write(line)

Categories