Adding Loop in the File Command Python - 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()

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

Why do I get a 'valueError' despite explicitly returning the expected number of values?

This is merge sort tweaked to count inversions. My code throws an odd error
(I'm implementing algos to learn python 3.x).
In line 11,
in merge_sort first_sorted_half, x = merge_sort(arr[:half])
[Previous line repeated 12 more times] ValueError: not enough values
to unpack (expected 2, got 1)
Even though I explicitly return two values? I'm new to python 3 so I'd like to understand exactly what's going on here, I can't seem to find a similar issue anywhere. A link to python docs for more on this would also be appreciated!
def merge_sort(arr):
if len(arr) <= 1:
return arr
half = int(len(arr)/2)
first_sorted_half, x = merge_sort(arr[:half])
second_sorted_half, y = merge_sort(arr[half:])
merged_halves, z = merge(first_sorted_half, second_sorted_half)
return merged_halves, x + y + z
def merge(first_half, second_half):
n = len(first_half) + len(second_half)
i = 0
j = 0
split_inversions = 0
ans = []
for k in range(n):
if i >= len(first_half):
ans.append(second_half[j])
j += 1
continue
if j >= len(second_half):
ans.append(first_half[i])
i += 1
continue
if first_half[i] > second_half[j]:
ans.append(second_half[j])
j += 1
split_inversions += len(first_half) - i
elif first_half[i] < second_half[j]:
ans.append(first_half[i])
i += 1
return ans, split_inversions
numbers = [3,2,1,4,5,6,8,10,9]
print(merge_sort(numbers))
The error you are getting says that your program executed that recursive call 12 times, and at the end it couldn't unpack the result.
What that means is, python expects you to return two values from merge_sort, because you unpack the result into first_sorted_half and x. However, when you return only arr from the condition len(arr) <=1, there is no value to unpack, only there exists the array.
So how you fix that is returning a value for the base case, like return arr, len(arr).
Whilst ilke444 is right - a bit more clarification is needed. To start: returning data variables is what you need but I do not know much about the len(arr) <=1 , and I am quite new to stackflow, I do not know this feature of Python 3. I specialize in Pygame/ standard packages.
First thing - arr in this "Code Snippet" (If it is) is not defined; and/or will need to be defined. Len stands for length as you know - and uses a quote (' ') to use it.
Like so:
len('arr')
would print:
3
because there are 3 Characters in this set. You are obviously new to python 3 as you said because the syntax is slightly different.
As this probably only solves the first bit - with this info I will leave you with 1 thing more.
Call to print requires a quote (' '),
Lists have [ ] Brackets instead of (),
Dictionaries have {} brackets and variables now require definition either by variable definition or function unless put in quote marks.
Thanks,
Jerry

Why is the written python file 5120 bytes in size?

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

Input on same line in Python

I have a problem with an output in Python
I'm trying to have an input in the form
2
1 10
2 20
2 being the number of tests and each line representing the number used by the function
To be able to have a single output, I'm storing the values in a tab in Python. The problem is that my tab doesn't have the correct values. Using the values given before, I have the following result when looking into the tab
1 2 20 5
Here's my code, thanks :
nbTest = input()
Tab = range(1,2*nbTest + 2)
for i in range(1,nbTest + 1):
a,b = map(int,sys.stdin.readline().split())
Tab[i] = a
Tab[i+1] = b
i = i + 1
print Tab[1], Tab[2], Tab[3], Tab[4]
First you don't have to "initialize" a list in python, so
Tab = range(1,2*nbTest + 2)
is unnecessary.
Second: the line
i = i + 1
doesn't do anything since the variable i is reassigned immediately afterwards.
Third: You should append tuples of values to your output list like this:
nbTest = int(raw_input())
inputs = []
for i in range(0,nbTest):
a,b = map(int, raw_input().split())
inputs.append((a,b))
print nbTest
for el in inputs:
print el[0], el[1]
Your should not modify the loop variable i inside the loop.
The line i = i + 1 does nothing since i is reassigned by the for loop, so you overwrite the Tab[i+1] of the previous iteration with Tab[i]. If you want i to increase by 2 at each iteration use range(1, nbTest+1, 2) instead.
Also note that you don't have to initialise the size of your list, you can simply do Tab=list(), and then use Tab += [a,b]
Also, pythons arrays start at 0, so your range must be start from 0 as well. Otherwise the first slot of the list will not be replaced.
Note If you are using python3, you must do Tab = list(range(1, 2*nbTest+2)) if you want Tab to be a list.

How to properly use the print function

while index < len(diecount):
print(index)
for number in range(diecount[index]):
print('*')
index+=1
print("")
At the moment i am getting
1
**
2
3
**
i want the output to be
1 **
2
3 **
A more Pythonic way to write this:
for index, count in enumerate(diecount[1:], start=1):
print(index, '*' * count)
(Manually controlling loop indexes in a while is usually a sign you're trying to write C code in Python).
Each print function appends a newline at the end of whatever it currently prints.
You can append a space instead of newline after the first print using the 2nd argument:
print(index, end = " ")

Categories