Writing and naming multiple files in python - python

The following code writes multiple files with certain number of lines from "t.txt" and name each file with the increasing line count. Now I want to write all files with name "1, 2, 3, 4, 5, 6, 7, 8..." or "mya, myb, myc, myd...". How do I change the code?
9 with open ("t.txt") as f:
10 probelist = [x.strip() for x in f.readlines()]
11 for i in probelist:
12 if not itemcount % filesize:
13 outfile = open("{}".format(filenum).zfill(8), "w")
14 filenum += 1
15 outfile.write(i+"\n")
16 itemcount += 1
17 outfile.close()

You can use itertools.islice to get filesize slice using enumerate to get get a unique name for each file, passing 1 as the start to enumerate to start the indexing at 1:
from itertools import islice
with open("t.txt") as f:
for ind, sli in enumerate(iter(lambda:list(islice(f,filesize)),[]),1):
with open("{}.txt".format(ind),"w") as out:
out.writelines(sli)

I added "file_count" to do what I assumed "filenum" was doing. Does this do the job for you? Sorry about the earlier confusion; I was paying attention to the variable name instead of the definition.
file_count = 1
with open ("t.txt") as f:
probelist = [x.strip() for x in f.readlines()]
for i in probelist:
if not itemcount % filesize:
file_name = str(file_count) + ".txt"
outfile = open(file_name, "w")
file_count += 1
filenum += 1
outfile.write(i+"\n")
itemcount += 1
outfile.close()

Related

Median of 8 values from a text file

I have a text file with like 36000 values. One value in each row.
I need to calculate the median of 8 values then move to the next 8 values and so on. This is the code i've written so far.
num_lines = open('median_raw.txt').read().count('\n')
print(num_lines)
median_values =0
count2 = count1
while count2<=num_lines:
file_name = open("median_raw.txt", 'r+')
f= open('median_parsed' + '.txt', 'w+')
for line_no1, line1 in enumerate (file_name):
median_values=(statistics.median([line1, int(next(line1))]))
f.writelines([median_values])
count2= count2+8
file_name.close()
f.close()
Here is something more idiomatic. It is using islice from itertools which reads in the lines 8 at a time, holding only 8 in memory at one time. So for a larger file you wont see issues with memory.
from itertools import islice
from statistics import median
with open('median_raw.txt') as f, open('median_parsed.txt', 'w+') as fout:
while True:
val = [int(s) for s in islice(f, 8)]
if not val:
break
avg = median(val)
print(f'the median of {val} is {avg}')
fout.write(f'{avg}\n')
This should work fine even if the number of lines in the input aren't divisble by 8. We stop iterating when islice returns at empty list.
Maybe try this:
file_name = open("median_raw.txt", 'r+')
f = open('median_parsed.txt', 'w+')
for bin in range(len(open('median_raw.txt').read().count('\n'))/8):
median_values=(statistics.median(file_name[8*bin:8 + 8*bin]))
f.writelines([median_values])
f.close()
Line 1 will create a range for you to iterate through your file in sets of 8.
Each new loop will then collect the mean of 0 to 8 modulated by the current 'bin'.
This will only work if your starting file newline length is divisible by 8

How to jump to the beginning of the next column when adding new data into text file?

I have written a python script which starts with an empty .txt file. It adds a series of numeric data into first column of the file and then it closes the file. The code is actually running 3 times and it is supposed to print data into a new column presumably after inserting an empty column so that by the end of the code, we should end up with a .txt file which has 3 columns of data corresponding to 3 runs. I have managed to set the code to run three times and produce 3 1d arrays with known elements (known as "some_array").
Here is the snippet of the code that writes data into a .txt file.
# "some_array" which is updated for each run
data = "<Path to data.txt>"
with open(data,"a") as fName:
for item in some_array:
print('{:.2e}'.format(item), file=fName)
fName.close()
Which would result in the following output:
(Unfortunately, all data are added at the end of the previous set of data)
1.00e-3
2.00e-3
3.00e-3
4.00e-3
5.00e-3
6.00e-3
7.00e-3
8.00e-3
9.00e-3
Is there any way to insert an empty column and jump to the beginning of the next column right before closing the file? This way I can get three columns of data, something like this:
1.00e-3 4.00e-3 7.00e-3
2.00e-3 5.00e-3 8.00e-3
3.00e-3 6.00e-3 9.00e-3
You can do something like this. Each time you read the file content first and then writing back the content to file, you can prepend previous information.
data = "file.txt"
array1 = [1, 2, 3, 4, 5]
with open(data, "r") as fName:
content = fName.readlines()
content = [x.strip() for x in content]
with open(data, "w") as fName:
for i in range(len(array1)):
if len(content) > i:
print(content[i] + '\t' + '{:.2e}'.format(array1[i]), file=fName)
else:
print('{:.2e}'.format(array1[i]), file=fName)
array2 = [6, 7, 8, 9, 10]
with open(data, "r") as fName:
content = fName.readlines()
content = [x.strip() for x in content]
with open(data, "w") as fName:
for i in range(len(array2)):
if len(content) > i:
print(content[i] + '\t' + '{:.2e}'.format(array2[i]), file=fName)
else:
print('{:.2e}'.format(array2[i]), file=fName)
array3 = [11, 12, 13, 14, 15]
with open(data, "r") as fName:
content = fName.readlines()
content = [x.strip() for x in content]
with open(data, "w") as fName:
for i in range(len(array3)):
if len(content) > i:
print(content[i] + '\t' + '{:.2e}'.format(array3[i]), file=fName)
else:
print('{:.2e}'.format(array3[i]), file=fName)
Please note, this is just an example, you can modify it to achieve your target task
If you can keep all your data in memory then the easiest is to zip them for writing:
# run_computation(j) returns the j-th data array
some_arrays = [run_computation(j) for j in range(n_columns)]
data = "<Path to data.txt>"
with open(data,"wt") as fName:
for item in zip(*some_arrays):
print(' '.join(n_columns * ['{:.2e}']).format(*item), file=fName)

Find sum of numbers in line

This is what I have to do:
Read content of a text file, where two numbers separated by comma are on each line (like 10, 5\n, 12, 8\n, …)
Make a sum of those two numbers
Write into new text file two original numbers and the result of summation = like 10 + 5 = 15\n, 12 + 8 = 20\n, …
So far, I've got this:
import os
import sys
relative_path = "Homework 2.txt"
if not os.path.exists(relative_path):
print "not found"
sys.exit()
read_file = open(relative_path, "r")
lines = read_file.readlines()
read_file.close()
print lines
path_output = "data_result4.txt"
write_file = open(path_output, "w")
for line in lines:
line_array = line.split()
print line_array
You need to have a good understanding of python to understand this.
First, read the file, and get all of the lines by splitting it with a line feed (\n)
For each expression, calculate the answer and write it. Remember, you need to cast the numbers to integers so that they can be added together.
with open('Original.txt') as f:
lines = f.read().split('\n')
with open('answers.txt', 'w+') as f:
for expression in lines: # expression should be in format '12, 8'
nums = [int(i) for i in expression.split(', ')]
f.write('{} + {} = {}\n'.format(nums[0], nums[1], nums[0] + nums[1]))
# That should write '12 + 8 = 20\n'
Make your last for loop look like this:
for line in lines:
splitline = line.strip().split(",")
summation = sum(map(int, splitline))
write_file.write(" + ".join(splitline) + " = " + str(summation) + "\n")
One beautiful thing about that way is that you can have as many numbers as you want on a line, and it will still display correctly.
Seems like the input File is csv so just use the csv reader module in python.
Input File Homework 2.txt
1, 2
1,3
1,5
10,6
The script
import csv
f = open('Homework 2.txt', 'rb')
reader = csv.reader(f)
result = []
for line in list(reader):
nums = [int(i) for i in line]
result.append(["%(a)s + %(b)s = %(c)s" % {'a' : nums[0], 'b' : nums[1], 'c' : nums[0] + nums[1] }])
f = open('Homework 2 Output.txt', 'wb')
writer = csv.writer(f, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
for line in result:
writer.writerow(line)
The output file is then Homework 2 Output.txt
1 + 2 = 3
1 + 3 = 4
1 + 5 = 6
10 + 6 = 16

Python use for loop to read specific multiply lines from txt files

I want use python to read specific multiply lines from txt files. For example ,read line 7 to 10, 17 to 20, 27 to 30 etc.
Here is the code I write, but it will only print out the first 3 lines numbers. Why? I am very new to use Python.
with open('OpenDR Data.txt', 'r') as f:
for poseNum in range(0, 4):
Data = f.readlines()[7+10*poseNum:10+10*poseNum]
for line in Data:
matAll = line.split()
MatList = map(float, matAll)
MatArray1D = np.array(MatList)
print MatArray1D
This simplifies the math a little to choose the relevant lines. You don't need to use readlines().
with open('OpenDR Data.txt', 'r') as fp:
for idx, line in enumerate(fp, 1):
if idx % 10 in [7,8,9,0]:
matAll = line.split()
MatList = map(float, matAll)
MatArray1D = np.array(MatList)
print MatArray1D
with open('OpenDR Data.txt') as f:
lines = f.readlines()
for poseNum in range(0, 4):
Data = lines[7+10*poseNum:10+10*poseNum]
You should only call readlines() once, so you should do it outside the loop:
with open('OpenDR Data.txt', 'r') as f:
lines = f.readlines()
for poseNum in range(0, 4):
Data = lines[7+10*poseNum:10+10*poseNum]
for line in Data:
matAll = line.split()
MatList = map(float, matAll)
MatArray1D = np.array(MatList)
print MatArray1D
You can use a combination list slicing and comprehension.
start = 7
end = 10
interval = 10
groups = 3
with open('data.txt') as f:
lines = f.readlines()
mult_lines = [lines[start-1 + interval*i:end + interval*i] for i in range(groups)]
This will return a list of lists containing each group of lines (i.e. 7 thru 10, 17 thru 20).

How to make Python read new lines and just lines?

I know that Python can read numbers like:
8
5
4
2
2
6
But I am not sure how to make it read it like:
8 5 4 2 2 6
Also, is there a way to make python read both ways? For example:
8 5 4
2
6
I think reading with new lines would be:
info = open("info.txt", "r")
lines = info.readlines()
info.close()
How can I change the code so it would read downwards and to the sides like in my third example above?
I have a program like this:
info = open("1.txt", "r")
lines = info.readlines()
numbers = []
for l in lines:
num = int(l)
numbers.append(str(num**2))
info.close()
info = open("1.txt", "w")
for num in numbers:
info.write(num + "\n")
info.close()
How can I make the program read each number separately in new lines and in just lines?
Keeping them as strings:
with open("info.txt") as fobj:
numbers = fobj.read().split()
Or, converting them to integers:
with open("info.txt") as fobj:
numbers = [int(entry) for entry in fobj.read().split()]
This works with one number and several numbers per line.
This file content:
1
2
3 4 5
6
7
8 9 10
11
will result in this output for numbers:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
This approach reads the whole file at once. Unless your file is really large this is fine.
info = open("1.txt", "r")
lines = info.readlines()
numbers = []
for line in lines:
for num_str in line.split(' '):
num = int(num_str)
numbers.append(str(num**2))
info.close()
info = open("test.txt", "r")
lines = info.readlines()
numbers = []
for l in lines:
l = l.strip()
lSplit = l.split(' ')
if len(lSplit) == 1:
num = int(l)
numbers.append(str(num**2))
else:
for num in lSplit:
num2 = int(num)
numbers.append(str(num2**2))
print numbers
info.close()
A good way to do this is with a generator that iterates over the lines, and, for each line, yields each of the numbers on it. This works fine if there is only one number on the line (or none), too.
def numberfile(filename):
with open(filename) as input:
for line in input:
for number in line.split():
yield int(number)
Then you can just write, for example:
for n in numberfile("info.txt"):
print(n)
If you don't care how many numbers per line, then you could try this to create the list of the squares of all the numbers.
I have simplified your code a bit by simply iterating over the open file using a with statement, but iterating over the readlines() result will work just as well (for small files - for large ones, this method doesn't require you to hold the whole content of the file in memory).
numbers = []
with open("1.txt", 'r') as f:
for line in f:
nums = line.split()
for n in nums:
numbers.append(str(int(n)**2))
Just another not yet posted way...
numbers = []
with open('info.txt') as f:
for line in f:
numbers.extend(map(int, line.split()))
file_ = """
1 2 3 4 5 6 7 8
9 10
11
12 13 14
"""
for number in file_ .split():
print number
>>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Categories