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?

2
  • 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. Commented Apr 20, 2017 at 1:32
  • 3
    Start here Commented Apr 20, 2017 at 1:32

3 Answers 3

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).

Sign up to request clarification or add additional context in comments.

2 Comments

I think you still have to worry about exceptions. The file might not exist, or permissions disallow opening
@cricket_007 clarified
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

1 Comment

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()).
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).

5 Comments

You're reading the whole filename into the memory needlessly here
I may be getting confused by the term filename. Wouldn't you need the filename?
Sorry... autocomplete. The whole file... And for line in file, is actually not a line at all, but a character
@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
The regex version isn't mine. It was what the question used. So 100 + 1 is much different answer than 1+0+0+1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.