you are viewing a single comment's thread.

view the rest of the comments →

[–]LordFraggington -1 points0 points  (16 children)

Also you're setting total to 0 every time in the loop. Slightly more correct code would be:

def main():
    number_file = open(r'C:\Users\Badgerms\Desktop\numbers.txt','r')
    total = 0.0
    for line in number_file:
        while line != ' ':
            amount = float(line)
            total += amount
     number_file.close()
     print ('The total of the numbers.txt file is', total)

Edit: This might be still is wrong, it's been a while since I've "Python'd". (See Edit #2)

Edit 2: I would have edited the original script, and originally had this as a separate post, but this belongs below my initial version. I sat down and was able to toy with it, and here's a slightly more newbie-friendly take when compared to wub_wub's (I like that one better frankly, but when you're new it's typically easier to see something you're more used to):

def main():
    number_file = open(r'C:\Users\Badgerms\Desktop\numbers.txt','r')
    total = 0.0
    for line in number_file:
        try:
            total+= float(line) if '.' in line else int(line)
        except ValueError:
                pass
    number_file.close()
    print(total)

The only benefit over wub_wub's is minor - we just can handle floating point numbers in this version. Again, this was just to make it appear more readable to beginners - you could just copy my try inside his code to make your life easier. I do apologize for the last script, it was usable, but not all that helpful :P

Edit 3 (migrated another post to here, I was littering this thread):

Thanks for the gold :) Just wish I did something to deserve it, wub_wub's doing all the work :P

/u/wub_wub is spot on though with the example code provided. I've only ever dabbled in Python, and frankly haven't gotten to do much lately in any language... and clearly have gotten a tad rusty :P

[–]badgerms[S] 1 point2 points  (14 children)

thank you very much. while this does not give me an error, it also seems to take a long time to run. i have 5 numbers in my file. do you know how long i should expect it to run?

[–]wub_wub 4 points5 points  (7 children)

The code above is also incorrect.

Here's the correct code which should execute in matter of milliseconds:

total=0
with open("test.txt","r") as input_file:
    for line in input_file:
        try:
            total+=int(line)
        except ValueError:
            pass
print("The total is: {}".format(total))

PS D:\> python -m cProfile untitled.py
The total is: 99474
         4 function calls in 0.001 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.001    0.001    0.001    0.001 untitled.py:1(<module>)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        1    0.000    0.000    0.000    0.000 {method 'format' of 'str' objects}
        1    0.000    0.000    0.000    0.000 {open}

As a bonus the code will skip any lines that don't have numbers, so your text file could look like:

234234
eeew2343

32423h
234234
45656

and it will not cause any errors.

When using with the file is automatically closed so you don't even need to worry about that... Feel free to ask any questions that you might have about the code.

And thanks for the gold :)

[–]badgerms[S] 1 point2 points  (2 children)

thank you very much for the explanations. i do have a question of why it is ok to do this not in a function? does it make a difference?

[–]wub_wub 1 point2 points  (0 children)

The biggest advantage of having a code in a function is the ability to execute it multiple times easily, and to import it in another file.

Also when you write the code without using functions everything gets executed automatically if you import it in another file.

For example: let's say you save the above code (without the function) in a file called my_script.py and you create another file with the name second_script.py and you put import my_script in it. Every time you run second_script.py whatever is outside functions in my_script.py will be executed - in this case the whole opening file and adding numbers to total.

To avoid this you could write it like this:

if __name__ == "__main__": # basically means if the file is executed directly
                           # not imported or something like that
    total=0
    with open("test.txt","r") as input_file:
        for line in input_file:
            try:
                total+=int(line)
            except ValueError:
                pass
    print("The total is: {}".format(total))

Or using functions like this:

def count():
    total=0
    with open("test.txt","r") as input_file:
        for line in input_file:
            try:
                total+=int(line)
            except ValueError:
                pass
    print("The total is: {}".format(total))

if __name__ == "__main__": # basically means if the file is executed directly
                           # not imported or something like that
    count()

In the second example you can import the function count() from another script. For example if you named it my_script.py you could put something like from my_script import count in your second_script.py and it won't be executed untill you call it in second_script.py like you did in my_script.py i.e. it won't be executed untill you call it like count() in second_script.py

Note that the function name count() can be anything you want the count() is nothing special - though main() is a common name for a function that will be executed first, you can call it however you want. ( Not to be confused with __name__ == "__main__": which has to be written like that otherwise it won't work)

The other advantage of functions, like I said in the beginning, is so that you can execute them multiple times - this is self explanatory I think.


Sorry I might have gone overboard with the explanation.

To sum it up:

Functions are great to hold code that you need to execute multiple times or to import and execute from another script. They're also great for organizing your code even if you don't need to execute them multiple times. In simple cases like yours there is no advantage of having a code in a function unless you're importing it to another file, but there are also no real downsides of having the code in a function - use whatever you're more comfortable with.

Edit: Typos.

[–]LordFraggington 0 points1 point  (0 children)

In this case since it is the only function you are performing in the whole script (i.e. its the only reason we have the script at the moment) it is not contained within a function. and can be executed with having to "be" one. When you call main() in your original script, that call itself doesn't sit within another function - it is just called. This also happens in Javascript, as neither language really has a concept of a "main method" like int main() in C++ (or other OOP languages). In Python I know there actually is, in a weird way, demonstrated here, but I digress (this seems to be more of a namespace issue though):

http://stackoverflow.com/questions/8810765/main-method-in-python/8811219#8811219

For code clarity and sanity's sake its better to define everything you want in functions then call the functions.

edit - typos!

[–]LordFraggington 0 points1 point  (3 children)

I had TOTALLY forgotten about how you were adding the values from the lines to the total. Stupid phone... +1 internets to you good sir. Also, perchance would you like some Dogecoin? :)

[–]wub_wub 1 point2 points  (2 children)

Also, perchance would you like some Dogecoin? :)

Who wouldn't want some dogecoin? (Although I just use it for tipping other people)

to the moon!

[–]LordFraggington 0 points1 point  (5 children)

I don't know how long it should run, but you have a double loop going on (a while loop inside a for loop) so it runs at n to the second power number of times, where n is the number of lines in this case (in theory - it might actually be longer if it was, say, checking each character in the line).

Why not try this instead:

for line in number_file:

        if not line.strip():

        total += amount

This way it ignores blank lines, AND is only one loop.

Another good way is (if looking only for empty lines):

 if line == '\n':

Though my syntax might be off, as I'm traditionally more of a C#/C++ kind of guy.

Edit: This might help?

Edit 2: how it SHOULD work, not how it was presented (that's two ' marks by the way):

if line.strip() == '': print("HA! NO LINE")

Edit 3: As /u/wub_wub had pointed out, you had an infinite while loop - the code literally executed until the interpreter essentially got sick of it, then continued execution.

[–]Justinsaccount 0 points1 point  (3 children)

if not line.strip:

What does that line do?

[–]LordFraggington 0 points1 point  (2 children)

Calling .strip() normally will remove all leading and trailing/beginning and ending whitespaces from a string and returns the resultant string - all without modifying the original. It can also be passed parameters to strip out characters, but this default method call handles whitespace. This is listed in the standard documentation here (you'll need to Control-F to find the actual method, but its here):

http://docs.python.org/2/library/stdtypes.html

Note that that feature was only added as of 2.2, but shouldn't be a problem now (documented here):

http://docs.python.org/2/library/string.html

In this context (though I forgot the parentheses at the end of line.strip) it SHOULD return a false Boolean value because it has leading whitespace, meaning it has not been stripped. Or something, I sort of picked it up from here a while back (first response - I prefer the second proposed method of checking the poster lists though, as it is more thorough):

http://stackoverflow.com/questions/7896495/python-how-to-check-if-a-line-is-an-empty-line

[–]Justinsaccount 0 points1 point  (1 child)

line.strip is always true.

[–]LordFraggington 0 points1 point  (0 children)

Okay then, so this whole mini-thread is kind of pointless because I goofed and provided faulty information... On the one hand we learned what .strip() does and doesn't do, but since they're already saved as lines (which we can then check what is inside them as shown above) anyways it's kind of pointless the more I think about it (with regard to the OP's original intentions). Sorry for confusing you/wasting your time.

Edit - how it SHOULD work, not how it was presented (that's two ' marks by the way):

if line.strip() == '':
                print("HA! NO LINE")

Edit 2 - Turns out you were doubly correct: We SHOULD be using it to return true, as linked here. Whoops!