Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
File Reading
#1
This assignment is technically complete according to my instructions, but I would like to polish it up a bit for my own learning experience. Basically, I was tasked to display 15 numbers in a file, then calculate the average of said numbers.

# Initialize constants
total = 0
lines = 0
file = 0
average = 0

# Gather all numbers in file for display
with open('numbers.dat', 'r') as file:
    lines = file.read()

# Add all numbers in file
for add in open('numbers.dat'):
    total += int(add.strip())

# Calculate the average of numbers in file
average = total / 15
average = round(average, 2)

#Print all numbers in file
print('The numbers in the file are:')
print(lines)

# Print the average of numbers in file
print('The average of those numbers is:')
print(average)

# Close file
file.close()

# END #
Question 1:
In this line of code:
# Calculate the average of numbers in file
average = total / 15
average = round(average, 2)
How can I replace the "15" with the number of integers that are actually in the file? Say I wanted to put 20 numbers in there instead of 15 to calculate the average, I'd like the total to be divided by the amount of numbers there are, not just a constant.

Question 2: What can I add to ignore spaces in the file, and only use the numbers on each line? The code works fine if the numbers are in a nice column without any spaces; however, I get an error if there is a single space in between the numbers.

Please keep any suggestions as close to the initial code as possible, and thank you for reading this far.

Cheers.
Reply
#2
How are the numbers laying in the file? If there is a number for each line then you get the integers by getting the lines. if you have multiple numbers per line this would be a slightly different approach. I will assume that there is just a single number in each line, else please correct me :)
lets say you have red the lines of the file to the variable lines. now you could to this:
lines = [int(line.strip()) for line in lines if not line.strip == " "]
if you now say len(lines) you get the number of integers in your file.
if you have the numbers seperated by " " then think about splitting them using line.split(" ")
a little excerpt of you data would help :)
Reply
#3
sum_ = 0
numbers = 0
for line in lines:
    try:
        sum_ += int(line)
        numbers += 1
    except ValueError:
        pass
I am assuming that list comprehension is not allowed so here is one way to do it. It's readable and clear.

I just have learned something new. Stripping whitespace characters is not necessary to convert a string to an integer. I tried it couple of minutes ago.

>>> int('  \t10 \n')
10
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#4
To keep the code as similar as possible to yours, you can use:
# Add all numbers in file
n = 0
for add in open('numbers.dat'):
    total += int(add.strip())
    n += 1
 
# Calculate the average of numbers in file
average = total / n
But your code has many things to improve:
- It opens the file twice for no reason
- Initialises variables when is not needed (the only one needed is 'total')
- The last file.close() is redundant as the with block guarantees that the file is closed at exit.

The same in a more pythonic way:
# Notice that this will fail if there is a blank line in your input file
with open('numbers.dat', 'rt') as fd:
    numbers = [int(s.strip()) for s in fd]

average = round(sum(numbers) / len(numbers), 2)

print('The numbers in the file are:')
for n in numbers:
    print(n)
 
# Print the average of numbers in file
print('The average of those numbers is:')
print(average)
And you shall add also guards in case the file is empty to avoid dividing by 0 when you calculate the average.
Reply
#5
Thank you guys so much for your help. I literally learned something new from every response.

@ ThiefOfTime You are correct, the file is just a column of random numbers, single integer per row. The instructor will grade with his own data file, which is why I was looking to skip spaces in the off chance there were spaces in his file.

Again, thank you guys for the help!

@killerrex Quick question, why does this line:
numbers = [int(s.strip()) for s in file]
only accept brackets [] around the command, and it won't accept ()?
Reply
#6
In that form is just to create a list, as the [x for x in xxx] is a syntactic sugar for list(x for x in xxx).
In particular the part of "x for x in xxx" produces a generator, that you can pass it to any place in python that accepts a generator as input (behaves as the command "range")

The other 2 "pretty" syntax similar to that one is to create a set or a dictionary:
# Imagine fd contains 1, 2, 555, 44
# You only want the different numbers, no matter the repetitions => Create set of numbers
>>> {int(s.strip()) for s in fd}
{1, 2, 555, 44}

# You want to create a dictionary initialising the entry to something
>>> {int(s.strip()): 'xxx' for s in fd}
{1: 'xxx', 2: 'xxx', 44: 'xxx', 555: 'xxx'}

# If you want to create a tuple you can do it with:
>>> tuple(int(s.strip()) for s in fd)
(1, 2, 44, 555)
Reply
#7
As I'm looking at the assignment, they are not likely to passed the generators.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#8
@killerrex Wow, I didn't even realize doing it like that made the whole thing a list! Super nifty! TY for the explanation.

@wavic You're right, we definitely didn't learn about generators yet. This is my first Python class, so it's pretty lightweight. In fact, it mostly focuses on pseudocode, which is why I am asking what may seem like such easy solutions to you guys.
Reply
#9
We've all gone trough this. No one speaks Python at the age of one and a half
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#10
Thanks, man! Definitely something I'm glad you said. :)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Excel File reading vanjoe198 1 2,038 Mar-31-2021, 11:53 AM
Last Post: snippsat
  reading from a file looseCannon101 14 4,907 Jul-18-2020, 11:29 AM
Last Post: GOTO10
  Weird problem with reading from file and performing calculations pineapple999 1 2,999 Jul-25-2019, 01:30 AM
Last Post: ichabod801
  Handling IO Error / Reading from file Expel 10 4,832 Jul-18-2019, 01:21 PM
Last Post: snippsat
  Reading an Unconventional CSV file OzSbk 2 3,875 May-17-2019, 12:15 PM
Last Post: MvGulik
  reading text file and writing to an output file precedded by line numbers kannan 7 10,391 Dec-11-2018, 02:19 PM
Last Post: ichabod801
  Reading of structured .mat (matlab) file sumit 2 3,415 May-24-2018, 12:12 PM
Last Post: sumit
  reading all lines from a text file seadoofanatic 2 2,924 Mar-13-2018, 06:05 PM
Last Post: Narsimhachary
  Reading a text file fivestar 7 5,579 Oct-13-2017, 07:25 AM
Last Post: gruntfutuk
  Dictionary + File Reading palmtrees 2 4,872 Nov-15-2016, 05:16 PM
Last Post: Ofnuts

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020