2

im writing a python function to do the following, add numbers from each line, so i can then find the average. this is what my file looks like:

 -2.7858521
 -2.8549764
 -2.8881847
  2.897689
  1.6789098
 -0.07865
  1.23589
  2.532461
  0.067825
 -3.0373958

Basically ive written a program that does a for loop for each line, incrementing the counter of lines and setting each line to a float value.

   counterTot = 0      
   with open('predictions2.txt', 'r') as infile:
            for line in infile:
                counterTot += 1
                i = float(line.strip())

now is the part i get a lil stuck

   totalSum = 
   mean =  totalSum / counterTot
   print(mean)

As you can tell im new to python, but i find it very handy for text analysis work, so im getting into it.

Extra function

I was also looking into an extra feature. but should be a seperate function as above.

  counterTot = 0      
   with open('predictions2.txt', 'r') as infile:
            for line in infile:
                counterTot += 1
                i = float(line.strip())
                                    if i > 3:
                                        i = 3
                                    elif i < -3:
                                        i = -3

As you can see from the code, the function decides if a number is bigger than 3, if so, then make it 3. If number is smaller than -3, make it -3. But im trying to output this to a new file, so that it keeps its structure in tact. For both situations i would like to keep the decimal places. I can always round the output numbers myself, i just need the numbers intact.

RHK-S8
  • 317
  • 1
  • 3
  • 11

5 Answers5

5

You can do this without loading the elements into a list by cheekily using fileinput and retrieve the line count from that:

import fileinput

fin = fileinput.input('your_file')
total = sum(float(line) for line in fin)
print total / fin.lineno()
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
3

You can use enumerate here:

with open('predictions2.txt') as f:
     tot_sum = 0
     for i,x in enumerate(f, 1):
         val = float(x)
         #do something with val
         tot_sum += val           #add val to tot_sum 
     print tot_sum/i              #print average

#prints -0.32322842
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
3

I think you want something like this:

with open('numbers.txt') as f:
    numbers = f.readlines()
    average = sum([float(n) for n in numbers]) / len(numbers)
    print average

Output:

-0.32322842

It reads your numbers from numbers.txt, splits them by newline, casts them to a float, adds them all up and then divides the total by the length of your list.

bwind
  • 705
  • 5
  • 7
  • 1
    I don't you should use `numbers = open('numbers.txt').readlines()`; you can't close the file. In addition, using the `with` statement is better. – Rushy Panchal Jun 06 '13 at 13:54
  • You're right. I've updated the code example so it closes the file automatically. – bwind Jun 06 '13 at 14:06
1

Do you mean you need to change 5.1234 to 3.1234 and -8.5432 to -3.5432 ?

line = "   -5.123456   "

i = float(line.strip())

if i > 3:
    n = int(i)
    i = i - (n - 3)

elif i < -3:
    n = int(i)
    i = i - (n + 3)

print(i)

it give you

-3.123456

Edit:

shorter version

line = "   -5.123456   "

i = float(line.strip())

if i >= 4:
    i -= int(i) - 3

elif i <= -4:
    i -= int(i) + 3

print(i)

Edit 2:

If you need to change 5.1234 to 3.0000 ("3" and 4x "0") and -8.7654321 to -3.0000000 ("-3" and 7x "0")

line = "   -5.123456   "

line = line.strip()

i = float(line)

if i > 3:
    length = len(line.split(".")[1])
    i = "3.%s" % ("0" * length) # now it will be string again

elif i < -3:
    length = len(line.split(".")[1])
    i = "-3.%s" % ("0" * length) # now it will be string again


print(i)
furas
  • 134,197
  • 12
  • 106
  • 148
0

Here is a more verbose version. You could decide to replace invalid lines (if any) by a neutral value instead of ignoring it

numbers = []
with open('myFile.txt', 'r') as myFile:
    for line in myFile:
        try:
            value = float(line)
        except ValueError, e:
            print line, "is not a valid float" # or numbers.append(defaultValue) if an exception occurred
        else:
            numbers.append(value)
print sum(numbers) / len(numbers)

For your second request here is the most straightforward solution (more solutions here)

def clamp(value, lowBound, highBound):
    return max(min(highBound, value), lowBound)

Applying it to our list:

clampedValues = map(lambda x: clamp(x, -3.0, 3.0), numbers)
Community
  • 1
  • 1
hoylpraal
  • 361
  • 2
  • 7