-2

So I was able to fix the first issue with you guys help but now that th program is running without any errors, it's not calculating the average correctly and I'm not sure why. Here's what it looks like:

def calcAverage():
with open('numbers.dat', 'r') as numbers_file:
    numbers = 0
    amount = 0

    for line in numbers_file:
        amount = amount + float(line)
        numbers += 1


average = amount / numbers
print("The average of the numbers in the file is:",average)
  • 1
    error shows that you have empty string in `line`. You get the sam error if you run `float('')` – furas Jul 13 '21 at 16:54
  • you run code in wrong order - you hace to convert float before you read next line. – furas Jul 13 '21 at 16:55
  • As of now, as pointed out by @furas, you're missing the first line, since the cursor advances at each `readline` call. – MatBBastos Jul 13 '21 at 16:56
  • Okay, thank you guys that fixes the problem. Thanks for the help! – Aiden Douglas Jul 13 '21 at 16:57
  • 1
    A newline character (`\n`) or carriage return (`\r`) will also give that error. – MatBBastos Jul 13 '21 at 16:57
  • Also, as shown in @Barmar's answer, prefer to use the `with` statement to handle files. That would be best in your `getNumbers` function too. – MatBBastos Jul 13 '21 at 17:01
  • Welcome to StackOverflow, Aiden ️ Please don't [modify your question's code by __solving issues asked__](https://meta.stackexchange.com/questions/88627/how-far-can-i-refactor-the-code-in-someone-elses-question), after asking. The answers should solve all issues given at first. – hc_dev Jul 13 '21 at 17:45

3 Answers3

2

You're reassigning line after you check whether line is empty in the while. The while test is testing the previous line in the file.

So when you get to the end, you read a blank line and try to add it to the amount, but get an error.

You're also never adding the first line, since you read it before the loop and never add that to amount.

Use a for loop instead of while, it will stop automatically when it reaches the end.

def calcAverage():
    with open('numbers.dat', 'r') as numbers_file:
        numbers = 0
        amount = 0
    
        for line in numbers_file:
            amount = amount + float(line)
            numbers += 1
    
    average = amount / numbers
    print("The average of the numbers in the file is:",average)

If you do want to use a while loop, do it like this:

while True:
    line = numbers_file.readline()
    if not line:
        break

    # rest of loop
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • The `for line in numbers_file:` is a suitable __Python-construct__ to [read a file line-by-line](https://stackoverflow.com/questions/53283718/reading-a-file-line-by-line-in-python)️ – hc_dev Jul 13 '21 at 17:05
0

Error shows that you have empty string in line.

You can get the same error with float('')

You run code in wrong order - you read new line before converting previous line.
And you should strip line because it still have \n

You need

line = numbers_file.readline()
line = line.strip()  # remove `\n` (and `\t` and spaces)

while line != '':

    # convert current line
    amount = amount + float(line)  

    numbers += 1

    # read next line
    line = numbers_file.readline()
    line = line.strip()  # remove `\n` (and `\t` and spaces)

You could also use for-loop for this

numbers = []

for line in numbers_file:
    line = line.strip()  # remove `\n` (and `\t` and spaces)
    if line:
       numbers.append( float(line) )
    #else:
    #   break

average = sum(numbers) / len(numbers)

and this could be reduced to

numbers = [float(line) for line in numbers_file if line.strip() != '']

average = sum(numbers) / len(numbers)
furas
  • 134,197
  • 12
  • 106
  • 148
0

Other answers illustrated how to read a file line-by-line. Some of them dealt with issues like reaching end-of-file (EOF) and invalid input for conversion to float.

Since any I/O and UI can be expected to give invalid input, I want to stress on validation before processing the input as expected.

Validation

For each line read from an input console or file alike, you should consider validating.

  • What happens if the string is empty? Converting an empty string input to float
  • What happens if the string contains special chars ? like commented by Mat
  • What happens if the number does not fit your expected float? (value range, decimal precision)
  • What happens if nothing read or reached end-of-file ? (empty file or EOF)

Advice: To make it robust, expect input errors and catch them.

(a) using try-except construct for error-handling in Python:

for line in numbers_file:
    try:
        amount = amount + float(line)
        numbers += 1
    except ValueError:
        print "Read line was not a float, but: '{}'".format(line)

(b) testing on input ahead: In a more simple way, you could also test manually using basic if statements like:

if line == "":  # on empty string received
    print("WARNING: read an empty line! This won't be used for calculating average.")  # show problem and consequences
    continue  # stop here and continue with next for-iteration (jump to next line)
hc_dev
  • 8,389
  • 1
  • 26
  • 38