reading values from txt file and passing in function - python-3.x

I have a txt file which has values x , y listed as
20
80
70.....
I wrote code to read the x and y but i am not sure what i am doing wrong .
def readTruth():
with open("Truth.txt") as f:
for line in f:
x_truth, y_truth = line.split("\n")
return x_truth,y_truth
def main():
x,y = readTruth()
print(x)
if __name__ == "__main__":
main()
I only see one value getting printed in x.

You are reading one line at a time. So you cannot access the values in the 2nd line while reading the first line. Splitting the line by the newline character "\n" will do nothing in this instance.
If you only have 2 lines in your text file, you could do something like this:
# Note here that I am lazy and used a string here instead of text file
a_string = "1\n2"
def readTruth():
x_truth, y_truth = a_string.split("\n")
return x_truth,y_truth
x,y = readTruth()
print(x) # 1
print(y) # 2
But I suspect you have more than just 2 values. You could refactor your text file to hold the 2 values on the same line, separated by a space or comma. If you do so, your solution will work. You would just need to split by the comma or space, whichever delimiter you choose to use.
If you must have each number on a separate line, then your solution won't work. You would need to add the results to a list of X values and a list of Y values:
# truth.txt:
# 1
# 2
# 3
# 4
#
f = open("truth.txt", "r")
def readTruth():
counter = 1
X_vals = []
Y_vals = []
for line in f.readlines():
# If it is an even numbered line, add to Y_vals
if counter % 2 == 0:
Y_vals.append(line.strip("\n"))
# Otherwise it is an odd numbered line, so add to X_vals
else:
X_vals.append(line.strip("\n"))
counter+=1
return X_vals, Y_vals
x,y = readTruth()
print(x) # ['1', '3']
print(y) # ['2', '4']
Based on comments from the question poster, I assume they have a blank line between each number in their text file. This means each number is on an odd numbered line. The quick solution, added onto my previous example, is to skip blank lines:
# truth.txt:
# 1
#
# 2
#
# 3
#
# 4
#
f = open("truth.txt", "r")
def readTruth():
counter = 1
X_vals = []
Y_vals = []
for line in f.readlines():
# Skip blank lines
if line.strip("\n") != "":
# If it is an even numbered line, add to Y_vals
if counter % 2 == 0:
Y_vals.append(line.strip("\n"))
# Otherwise it is an odd numbered line, so add to X_vals
else:
X_vals.append(line.strip("\n"))
counter+=1
return X_vals, Y_vals
x,y = readTruth()
print(x) # ['1', '3']
print(y) # ['2', '4']

We obtain the values ​​of X and Y:
def readTruth():
with open("Truth.txt") as f:
for line in f:
x_truth, y_truth = line.split("\n")
return x_truth,y_truth
def main():
x,y = readTruth()
print("Var_X = "+ str(x[0]))
print("Var_Y = "+ str(x[1]))
You can put the variables in a list for each X and Y

Related

I expect same output I want to remove letters from a list

I expect same result from these codes what wrong with the other one.
def remove_letters(list):
x = []
for i in range(len(list)):
if type(list[i]) == type(1):
x.append(list[i])
print(x)
return x
y = [1,'b', 'c',2]
remove_letters(y)
Output >> [1,2]
def remove_letters(list):
x = list
for i in range(len(list)):
if type(list[i]) == type('a'):
x.remove(list[i])
print(x)
return x
y = [1,'b', 'c',2]
remove_letters(y)
output>>
Traceback (most recent call last):
File "/Users/genesissales/PycharmProjects/1. Unbuquity [ 1, a, b, 2]/main.py", line 14, in <module>
remove_letters(y)
File "/Users/genesissales/PycharmProjects/1. Unbuquity [ 1, a, b, 2]/main.py", line 6, in remove_letters
if type(list[i]) == type('a'):
IndexError: list index out of range
Process finished with exit code 1
its giving an error. it seems that list is also being change by the
for loop.
I have edited the code to make it more readable and pythonic.
from copy import copy
# don't use list as variable name, it's a reserved keyword
def remove_letters(l): # actually only keeps integers
x = []
for item in l:
if isinstance(item, int):
x.append(item)
print(x)
return x
y = [1,'b', 'c',2]
remove_letters(y)
#Output >> [1,2]
def remove_letters(l): # does remove all strings
x = copy(l) # make a copy otherwise the y list from the outer scope is going to be altered! see https://stackoverflow.com/a/47264416/10875953
for i, item in reversed(list(enumerate(x))): # iterate in reverse order that way it doesn't matter if we delete, enumerate adds the index
if isinstance(item, str):
x.remove(i)
print(x)
return x
y = [1,'b', 'c',2]
remove_letters(y)

How can I change specific values in a text file?

I have two data files (Amin file and Volume file). form the first one want to find out the number in front of a string "Amin". Then I want to open the second file and check all of the volume numbers and if they are smaller than Amin change that specific number to Amin.
Amin file looks like the following:
GP_DEF 1 4 "Zeitintervall Q_Strg [s]" 2 9.00000000e+002 0.00000000e+000 1
GP_DEF 1 5 "Hmin [m]" 2 1.00000000e-002 0.00000000e+000 1.79769313e+308
GP_DEF 1 6 "VELMAX [m/s]" 2 1.50000000e+001 0.00000000e+000 1
GP_DEF 1 7 "Amin" 2 0.5 0.5 0.5
Volume file looks like the following:
SCALAR
ND 6813
ST 0
TS 0.0
0.207
0.313
0.423
0.595
0.930
0.714
0.590
0.1
1.652
the result should be like the following:
SCALAR
ND 6813
ST 0
TS 0.0
0.5
0.5
0.5
0.595
0.930
0.714
0.590
0.5
1.652
I have written a code not in a pythonic way but logically should work. But it does not create a result. My code is as following:
with open("VOLUMEN.dat") as f1, open('V_korr.dat', 'w') as out:
mylist = f1.read().splitlines()[0:4]
print(mylist)
for item in mylist:
out.write("%s\n" % item)
with open('hydro_as-2d.2dm', 'r') as f, open('Amin.txt', 'a') as outfile:
for line in f:
if line.startswith('GP_DEF 1 7 "Amin" '):
try:
line = line.strip()
columns = line.split()
Amin = float(columns[4])
print("{:.2f}".format(Amin), file=outfile)
except ValueError:
pass
with open("VOLUMEN.dat") as f1, open('V_korr.dat', 'w') as out:
for line in f1:
if line.startswith('GP_DEF 1 7 "Amin" '):
try:
line = line.strip()
columns = line.split()
Vol = float(columns[0])
if (V<Amin):
print("{:.2f}".format(Amin), file=outfile)
else :
print(line,file=outfile)
except ValueError:
pass
Please give a hint, where did i do a mistake? Thanks!
I'm not going to try to untangle your code, but rather try to give a tentative solution to your somewhat unclear problem. Here is my suggestion:
#! /usr/bin/env python
#
def find_amin(fname, pattern, idx=5, default=None):
"""Locate first matching line in fname and return field at offset idx
If pattern is not found return default value.
"""
with open(fname) as fd:
for line in fd:
if line.startswith(pattern):
return line.split()[idx]
else:
return default
def adjust_volume_file(fname, limit, skip=3, indent=3):
"""Return lines in fname as a list adjusting data smaller than limit
Do not change the first skip lines. Adjusted numbers are output
with a margin of indent spaces.
"""
margin = indent * " "
result = []
with open(fname) as fd:
for idx, line in enumerate(fd):
if idx > skip:
result.append(margin + str(max(float(line), limit)) + '\n')
else:
result.append(line)
return result
if __name__ == "__main__":
amin = float(find_amin('amin-file.txt', ' GP_DEF 1 7 "Amin"'))
adjusted_data = adjust_volume_file('VOLUMEN.dat', amin)
with open('V_korr.dat', 'w') as fd:
fd.writelines(adjusted_data)

Python 3 script for exporting a csv

Hi I have a csv file where there are two columns, one with numbers and one with letters in the following format:
1234 k
343 o
5687 uiuuo
All I want to do is to fill the blank rows with the previous values. I have written that code which saves my work in a new csv but I get an error that says:
b = w[1]
IndexError: list index out of range
This is my code
import csv
with open('col.csv', 'r') as f:
reader = csv.reader(f)
my_list = list(reader)
#print my_list[1]
#x = my_list[1]
#print x[0]
x = 0
for count in my_list:
w = my_list[x]
a = w[0]
b = w[1]
print (a, b)
#print 'a', a , 'b', b
if a == '' and b == '' and x < 3044:
h = x - 1
my_list[x] = my_list[h]
#print 'my_list[x]', my_list[x]
x = x + 1
#print my_list[x]
elif a != '' and b != '' and x < 3044:
my_list[x] = (a,b)
x = x + 1
# print my_list[x]
writer = csv.writer(open('C:/Users/user/Desktop/col2.csv', 'wb'))
#for count in my_list:
data = my_list
for row in data:
writer.writerow(row)
#print count
When you say
blank lines with previous values
I'm assuming that you want to turn:
1234 k
343 o
5687 uiuuo
Into
1234 k
1234 k
343 o
343 o
5687 uiuuo
You have quite a lot of problems with your code:
import csv
with open('col.csv', 'r') as f:
reader = csv.reader(f)
my_list = list(reader)
If you've commented it out you don't need to include it in your question
#print my_list[1]
#x = my_list[1]
#print x[0]
x = 0
for count in my_list:
You do know that your list doesn't contain counts, right? This is just code that lies. Don't do that. Also, if you want to enumerate over a list and get the index along with the value, that's what enumerate is for. It should be for x, value in enumerate(my_list)
w = my_list[x]
a = w[0]
b = w[1]
Your second row doesn't actually have two elements in it. That's why your code fails. Oops.
print (a, b)
#print 'a', a , 'b', b
This code here is a hot mess. Why are you limiting to x < 3044? h is some random variable name that has no meaning. Don't do that either.
if a == '' and b == '' and x < 3044:
h = x - 1
my_list[x] = my_list[h]
#print 'my_list[x]', my_list[x]
x = x + 1
#print my_list[x]
elif a != '' and b != '' and x < 3044:
my_list[x] = (a,b)
x = x + 1
# print my_list[x]
Don't open files like this, it's possible that they'll never get flushed to disk. Or the entire file won't in any case. Always use a with block!
writer = csv.writer(open('C:/Users/user/Desktop/col2.csv', 'wb'))
#for count in my_list:
data = my_list
for row in data:
writer.writerow(row)
#print count
So... there's an interesting assumption here - that your first row must not be empty. I mean, I guess it could, but then you're going to be writing empty rows, and maybe you don't want that. Also your provided input doesn't seem to match what you're doing, since you're not using a \t delimiter.
If you think about what you want to do you can come up with the steps pretty easily:
for each row in the input file
write out that row to the output file
if it's blank/empty, write out the previous row
So that's pretty straight forward then.
import csv
with open('input.csv') as infile, open('output.csv', 'w') as outfile:
reader = csv.reader(infile, delimiter='\t')
writer = csv.writer(outfile)
for row in reader:
writer.writerow(row)
This works - but it doesn't write the previous row if we've got a blank row. Hm. So how can we do that? Well, why not store the previous row? And if the current row is empty, we can write the previous one instead.
previous_row = [] # If the first row is empty we need an empty list
# or whatever you want.
for row in reader:
if not row:
writer.writerow(previous_row)
else:
writer.writerow(row)
previous_row = row
If you want to treat ['', ''] as an empty row, too you just have to tweak the code:
if not row and not all(row):
...
Now if the row is empty, or the row contains false-y items it will skip that one as well.
Try not to index elements of an empty list or assign them to variables.
Most easy way in your case would be simply clone a complete row.
import csv
with open('col.csv', 'r') as f:
reader = csv.reader(f)
my_list = list(reader)
for i in range(0,len(my_list)):
currentLine = my_list[i]
#Make sure it's not the first line and it's empty, else continue
if not currentLine and i > 0:
my_list[i] =my_list[i-1]
with open('C:/Users/user/Desktop/col2.csv','wb') as f:
writer = csv.writer(f)
for row in my_list:
writer.writerow(row)

Python - Receiving an TypeError

So the code below:
Takes a given square, and if it is an X does nothing. If the square has an O in it, it changes the O to an X and autofills the square above, below, to the left, and to the right.
#openFile(filename): This function opens and prints the users txt file for paint
#input: none
#output: The file that needs to be painted
def openFile(filename):
file = open(filename, 'r')
for line in file:
print(line)
file.close()
#convertFile(filename): This function is used to convert the .txt file into a 2D arrary
#input: none
#output: none
def convertFile(filename):
empty = []
filename = open(filename, 'r')
for line in filename:
line = line.rstrip("\n")
empty.append(list(line))
return empty
#getCoordinates(x,y): This function is used to get the coordinates the user wants to pain from
#input: user coordinates.
#output: none
def getCoordinates(x, y):
coordinates = []
userInt = 0
user = []
try:
user = input("Please enter a square to fill , or q to exit: ")
user.split()
coordinates.append(int(user[0]))
coordinates.append(int(user[2]))
except ValueError:
print("Enter a valid input!")
user = input("Please enter a square to fill, or q to exit: ")
user.split()
coordinates.append(int(user[0]))
coordinates.append(int(user[2]))
return coordinates
def printGrid(grid):
for innerList in grid:
for item in innerList:
print(item, end = "")
print()
#autoFill(board, row, col): This is the heart of the program and the recursive program
# use to fill the board with x's
#input: none
#output: none
def autoFill(grid, rows, cols):
if grid[cols][rows] == "X":
return 0
else:
grid[cols][rows] = "X"
if rows > 0:
autoFill(grid, rows - 1, cols)
if rows < len(grid[cols]) - 1:
autoFill(grid, rows + 1, cols)
if cols > 0:
autoFill(grid, rows, cols - 1)
if cols < len(grid) - 1:
autoFill(grid, rows, cols + 1)
def main():
coordinates = []
empty = []
while True:
filename = input("Please enter a filename: ")
openFile(filename)
empty = convertFile(filename)
coordinates = getCoordinates(len(empty), len(empty[0]))
empty = autoFill(empty(coordinates[0], coordinates[1]))
for item in empty:
s = ""
s.join(item)
for x in item:
s += str(x)
print(s)
if user == "q":
return 0
main()
output should look like:
Please enter a filename: input.txt
OOOOOOXOOOO
OOOOOXOOOOO
OOOOXOOOOOO
XXOOXOOOOOO
XXXXOOOOOOO
OOOOOOOOOOO
Please enter a square to fill, or q to exit: 1, 1
XXXXXXXOOOO
XXXXXXOOOOO
XXXXXOOOOOO
XXXXXOOOOOO
XXXXOOOOOOO
OOOOOOOOOOO
But when i type in the coordinate points i get:
empty = autoFill(empty(coordinates[0], coordinates[1]))
TypeError: 'list' object is not callable
Any guidance in fixing this issue will be much appreciated
The particular error you're asking about is happening because you're trying to call empty (which is a list, as returned by convertFile) as if it were a function.

Python Conway's Game of Life

I'm trying to make Conway's Game of Life where the user enters how big they want the grid and which cells start off as alive. Here's what I have:
def firstBoard(rows, cols, array):
myList = [[0]*cols for i in range(rows)]
for i in myList:
i.append(-1)
i.insert(0,-1)
myList.insert(0,[-1]* (cols+2))
myList.append([-1]* (cols+2))
while True:
rows = input("Enter the row or 'q': ")
if rows == 'q':
break
cols = input("Enter the column: ")
print()
myList[int(rows)][int(cols)] = 1
return myList
def nextGen(cols, rows, cur, nxt):
for i in range(1,rows-1):
for j in range(1,cols-1):
nxt[i][j] = processNeighbours(i, j, cur)
def processNeighbours(x, y, array):
nCount = 0
for j in range(y-1,y+2):
for i in range(x-1,x+2):
if not(i == x and j == y):
if array[i][j] != -1:
nCount += array[i][j]
if array[x][y] == 1 and nCount < 2:
return 0
if array[x][y] == 1 and nCount > 3:
return 0
if array[x][y] == 0 and nCount == 3:
return 1
else:
return array[x][y]
def printBoard(cols, rows, array):
for i in range(rows+2):
for j in range(cols+2):
if array[i][j] == -1:
print("#", end=" ")
elif array[i][j] == 1:
print(".", end=" ")
else:
print(" ", end=" ")
print()
def main():
rows = int(input("Please enter the number of rows: "))
cols = int(input("Please enter the number of columns: "))
myList = []
newList = []
myList = firstBoard(rows, cols, myList)
newList = myList
print()
generations = int(input("How many iterations should I run? "))+1
for gens in range(generations):
printBoard(cols, rows, myList)
nextGen(cols, rows, myList, newList)
myList, newList = newList, myList
main()
And if for the both the rows and columns I enter five and If I fill 3,4 4,4 5,4 i get this:
# # # # # # #
# #
# #
# . #
# . #
# . #
# # # # # # #
# # # # # # #
# #
# #
# . #
# . #
# . #
# # # # # # #
# # # # # # #
# #
# #
# . #
# . #
# . #
# # # # # # #
# # # # # # #
# #
# #
# . #
# . #
# . #
# # # # # # #
when for the second and fourth boxes the dots should be horizontal instead of vertical. Please help i've been working on this all day and I can't figure it out.
The problem is with your array initialization:
newList = myList
This isn't making a copy of myList, it's just making newList refer to myList, so then you only have one array. You can copy a 2D array like this:
from copy import copy, deepcopy
newList = deepcopy(myList)

Resources