2

I have a simple program which looks through a file, finds any numbers inside, and adds them up into a variable called running_total. My issue seems to be that my file name is the thing that is being read instead of its contents.

import re

file = input('Enter file name:')
open(file)
print(file)
running_total = None

for line in file:
    line = line.rstrip()
    numbers = re.findall("[0-9]+", line)
    print(numbers)
    for number in numbers:
        running_total += float(number)

print(running_total)

What am I missing?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Baruch Elias
  • 31
  • 1
  • 1
  • 3
  • 1
    you need to capture the return from `open`. It returns a file object, despite its name `file` is just a string. You will also need to ensure the file is closed after you have used it. `running_total = None` is wrong, it should be `running_total = 0`. The values are not interchangeable, adding to `None` is not a valid operation. – Paul Rooney Apr 20 '17 at 01:32
  • 3
    Start [here](https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files) – juanpa.arrivillaga Apr 20 '17 at 01:32

3 Answers3

4

file is a string denoting a filename when it comes out of the input function, and it remains a string. So when you iterate over it, you get the letters of the filename one by one. When you call open(file) that returns an object that can be iterated over to provide file content, but you are not currently giving that object a name or re-using it. You really mean something like:

file_name = input('Enter file name:')
file_handle = open(file_name)   # this doesn't change file_name, but it does output something new (let's call that file_handle)
for line in file_handle:
    ....
file_handle.close()

...although the more idiomatic, Pythonic way is to use a with statement:

file_name = input('Enter file name:')
with open(file_name) as file_handle:
    for line in file_handle:
        ....
# and then you don't have to worry about closing the file at the end (or about whether it has been left open if an exception occurs)

Note that the variable file_handle is an object whose class is called file (which is one of the reasons I've changed the variable names here).

jez
  • 14,867
  • 5
  • 37
  • 64
0

I think you'll want to start the running total to a number that can be added to.

Then, you need to get the file handle

And the regex makes rstrip unnecessary

running_total = 0
with open(file) as f: 
    for line in f:
        running_total += sum(float(x) for x in re.findall("[0-9]+", line))
print(running_total)

Also here

https://stackoverflow.com/a/35592562/2308683

Community
  • 1
  • 1
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • I would do `with open(file) as ...`, or at the very least put the resulting File object into a variable, so that you can cleanup after (file.close()). – Casey Kuball Apr 20 '17 at 07:23
0

Use "with open() as" to read your file, because it should close automatically. Otherwise you need to explicitly tell it to close the file.

Assigning running_total as None threw me errors, but giving it a value of 0 fixed this issue.

Also, instead of using regex and stripping lines, just use isnumeric(). This also removes the second for loop you're using, which should be more efficient.

file = input('Enter file name:')
with open(file, 'r') as f:
    file = f.read()
print(file)
running_total = 0
for line in file:
    if line.isnumeric():
        running_total += int(line)
print(running_total)

I tested this with a txt file containing numbers on their own rows and numbers imbedded in words and it correctly found all instances.

Edit: I just realized the poster wanted to sum all the numbers, not find all the instances. Changed running_total += 1 to running_total += int(line).

Superspork
  • 393
  • 2
  • 9
  • You're reading the whole filename into the memory needlessly here – OneCricketeer Apr 20 '17 at 07:32
  • I may be getting confused by the term filename. Wouldn't you need the filename? – Superspork Apr 20 '17 at 12:40
  • Sorry... autocomplete. The whole *file*... And `for line in file`, is actually not a line at all, but a *character* – OneCricketeer Apr 20 '17 at 15:41
  • @cricket_007 That makes more sense. Thank you. Sorry, I thought I missed something with filename. You can instead use list comprehension to do away with loading the entire file and it would work. As for line in file, yes it iterates through the characters. My code will only add individual character numbers together. If it is larger than 9, it doesn't work and your regex version is more suitable. Depends on purpose – Superspork Apr 20 '17 at 16:11
  • The regex version isn't mine. It was what the question used. So `100` + `1` is much different answer than `1+0+0+1`. – OneCricketeer Apr 20 '17 at 17:32