How can I change specific values in a text file? - python-3.x

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)

Related

reading values from txt file and passing in function

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

How To Add 2 values in a dictionary together if the key is duplicated?

So I have this project where it asks the user for the number of .txt files these files are titled 'day' and then the number in ascending order. The format of what's inside the code is a sport/activity(key) then a comma and the number of people doing the sport(value). What I want is it to give an output of all the sports from the text files and if the activity(key) is duplicated then it adds up the people doing it(value). And to top that all off I wanted the total people who were participating(all the values added together)
days = int(input("How many days of records do you have? "))
i = 0
list1 = []
d = {}
for i in range(days):
i += 1
file = 'day' + str(i)
f = open(file + '.txt')
a = []
for line in f:
line = line.replace(',' , ' ')
list1.append(line)
words = line.split()
d[words[0]] = words[1]
a.append[words[1]]
stripped_line = [s.rstrip() for s in d]
for key,value in d.items() :
print (key + "," + value)
print("In total:", a, "attendees.")
INPUT
User_input = 3
day1.txt
swimming,1000
fencing,200
athletics,600
gymnastics,1200
tennis,500
day2.txt
diving,600
swimming,1200
tennis,500
rugby,900
handball,500
hockey,2300
trampoline,200
day3.txt
swimming,400
gymnastics,1200
fencing,100
diving,400
tennis,600
rugby,600
EXPECTED OUTPUT
swimming: 2600
fencing: 300
athletics: 600
gymnastics: 2400
tennis: 1600
diving: 1000
rugby: 1500
handball: 500
hockey: 2300
trampoline: 200
In total: 13000 attendees.
CURRENT OUTPUT
swimming,400
fencing,100
athletics,600
gymnastics,1200
tennis,600
diving,400
rugby,600
handball,500
hockey,2300
trampoline,200
This is one approach using collections.defaultdict.
Ex:
from collections import defaultdict
days = int(input("How many days of records do you have? "))
result = defaultdict(int)
for i in range(days):
with open("day{}.txt".format(i)) as infile:
for line in infile:
key, value = line.strip().split(",")
result[key] += int(value)
for key,value in result.items():
print (key + "," + str(value))
print("In total: {} attendees.".format(sum(result.values())))

input error in Python3.6

t = int(input())
while t:
qu , pt = input().split(' ')
qu = int(qu)
pt = int(pt)
sd = []
for i in range(0,qu):
x = int(input()) # I think I am getting problem in this part of
sd.append(x)
hd , cw = 0 , 0
diff = pt / 10
cwk = pt / 2
for i in range(0,qu):
if sd[i] <= diff:
hd += 1
else:
if sd[i] >= cwk:
cw += 1
if hd == 2 and cw == 1:
print ('yes')
else:
print('no')
t -= 1
When I try to give input like '1 2 3' I get an an error like this
Traceback (most recent call last):
File "C:/Users/Matrix/Desktop/test.py", line 8, in <module>
x = int(input())
ValueError: invalid literal for int() with base 10: '1 2 3'
Why am I seeing this problem ? How do I rectify this ?
The issue is that you're passing it a string rather than an integer. When you typed "1 2 3," you left spaces, which are considered characters. Spaces cannot be cast as integers. If your set on having the input as number space number space number space, then I suggest you split the sentence at the whitespace into a list.
def setence_splitter(user_input):
# splits the input
words = text.split()
Now you have the list, words, which will have each individual number. You can call each individual number using its index in words. The first number will be words[0] and so on.

Python3.5 How to convert list of strings to int so I can sum up the total?

import re
numlist = list()
*total = 0*
handle = open('test.txt')
for line in handle:
line = line.rstrip()
x = re.findall('([0-9]+)', line)
if len(x) > 0:
*for nums in x:
numlist.append(nums)
value = int(nums)
total = total+value
print(total)*
example of test.txt file:
jhjkhjhhjkhjh 5678 kjhlkjsd lkjaksd 6578 8765 hnhdtriusnfasdasdweefgdf dfdf dfdfdfdferse5667 9876gjshdi ksdhsks k6453jjhkkk 9087jjskldnjck kjshhdck 9877
khhgjnh 8532 jnhyg 7634iutr jhgpiunegjd
wert 1234 kjhg 4567 kjh b 0987 jhggebndueh nhergsus df 9987 7654 0129kk jhikhhhgkjhhjiiksyehf 9876 ijh kjhgj 1234
If you just want to get all numbers and sum them your code works if you remove the asterisks and indent it properly. Indentation is crucial in python. And not sure why the asterisks are there?
import re
numlist = list()
total = 0
handle = open('test.txt')
for line in handle:
line = line.rstrip()
x = re.findall('([0-9]+)', line)
if len(x) > 0:
for nums in x:
numlist.append(nums)
value = int(nums)
total = total+value
print(total)
I would change it a little, and you don't mention what you want to use numlist for so I removed it in the following code.
import re
total = 0
with open('test.txt') as handle:
for line in handle:
x = re.findall('([0-9]+)', line)
for num in x:
total += int(num)
print(total)

Function is returning none and I don't know why

I have this code and for whatever reason, it returns none after it executes. Does anyone know why?
def function():
try:
ctr = 0
total = 0
file = open("text.txt", 'r')
while ctr <= 15:
ctr += 1
for line in file:
line = line.strip("\n")
num = float(line)
total += num
average = total / 15
return average
except ValueError:
total = total
After the Value Error, you are not returning anything.
except ValueError:
total = total
return ???
Are you sure the float(line) is not the source of an error that is causing a possible ValueError?
If I understand what you're trying to do, you want to read your file and compute the average of the numbers it contains, ignoring any lines that contain non-numbers. Your current code doesn't do this correctly because your try and except are at too high a level. You also have two loops where you probably only need one.
Try moving the exception handling inside of a single loop over the file contents:
def function():
ctr = 0
total = 0
with open("text.txt", 'r') as file: # a with statement will close the file for you
for line in file: # just one loop
try:
num = float(line) # this may raise an exception!
ctr += 1
total += num
except ValueError: # ignore ValueError exceptions in the loop
pass
if ctr > 0:
average = total / ctr
else:
average = 0 # or maybe raise an exception here, for a file with no numbers?
return average
If you need to limit the average to 15 values, you can probably add an extra check for ctr being greater than 15 in the loop. I left that part out because it wasn't clear from your non-working code what you wanted to do exactly (count lines or count numbers?).
Too much to put in the comments, but what is the output of this code?
def function():
average = 0
try:
ctr = 0
total = 0
file = open("text.txt", 'r')
while ctr <= 15:
ctr += 1
for line in file:
line = line.strip("\n")
num = float(line)
total += num
average = total / 15
return average
except ValueError as e:
total = total #What?
print("Caught ValueError")
return e
except Exception as e:
print("Caught Exception")
return e
print("At the end...")
return False
ve = function()

Resources