0

I stuck with one problem with my programming exercise thst sounds like:

  1. Write a simple program to first prompt the user to enter the filename of the text file that they wish to open. The program should then open the text file, read the contents of the file, and store this in a suitable Python data structure. Make sure you include a suitable exception handling (try ... except) structure that will inform the user if there is a problem loading the file and allows the user to enter an alternative filename if there is a problem.
  2. Once the data is successfully loaded, print out the data in a neatly formatted manner (see an example output below). 3). Calculate the average mark for each student and print these out with the data in task 3. Then also calculate the average mark for the class and print this out at the end.

Here is how the output shoul looks like:

Enter a filename: Student Marks.txt
Student Marks
Jean Paul Alarie:
Marks: 56.0, Average: 56.0
Juan Manuel Bienvenida:
Marks: 72.6, 12.0, Average: 42.3
Janet Brimfield:
Marks: 66.3, 71.0, Average: 68.65
Helen Jane Burnett:
Marks: 54.0, Average: 54.0
Bernard Galpin:
Marks: 45.0, 66.2, 32.0, Average: 47.73
…
Average: 54.26 

I know how to allow the user to enter a file and output its data to the screen, but I don't know how to make the output as shown in the sample and how to use operations on numbers in this case.

If you can help me and tell me how to solve it, I will be very grateful. Here is a sample of the code I have

while True:
            try:
                fname=input('Enter the file name: ')
                infile = open (fname, "r")
                data = infile.read()
                infile.close()
                print(data)
                print()

                count = 0
                total = 0
                i = 0
                while i < len(data):
                    print(data[i], ":", data [i+1])
                    count = count +1
                    total = total + float (data [i+1])
                    i=i+2
                print("avarage:", total/count)
            except:
                print("There was an Error")
                continue

And here is the output with an error:

Enter the file name: sm.txt
Student Marks
Jean Paul Alarie 56
Juan Manuel Bienvenida 72.6 12
Janet Brimfield 66.3 71
Helen Jane Burnett 54
Bernard Galpin 45 66.2 32
Alexander Adam Janssen 41 21
Struan Kilgour 79 82.5 45.5
Pierre Antoine Lajoie 56.2 45.5
Hamish McDonald 66.5 91
Shakeel Mirza 12
Sidney Rickard 88 78 84.4
Sharlene Urry 54.5
Karl James Richard White 62 59.5 41.2 66 

S : t
Traceback (most recent call last):
  File "C:/Users/Elf/Desktop/Essex lab/programming/spring term/week 20/ooooo.py", line 17, in <module>
    total = total + float (data [i+1])
ValueError: could not convert string to float: 't'
tab
  • 25
  • 4
  • 2
    What's the issue with the code sample that you provided? It looks complete. If there is an error, could you put the traceback in your post? – Blue Robin Mar 17 '23 at 00:00
  • 2
    Never write a bare `except:` clause. See [this question](https://stackoverflow.com/q/54948548). – InSync Mar 17 '23 at 00:07
  • @BlueRobin Yap, i have add it now – tab Mar 17 '23 at 00:07
  • The value error means that you're trying to convert a string to a float (which you can't do without it already being a number). – Blue Robin Mar 17 '23 at 00:08
  • 1
    Somehow your index `[i+1]` is not hitting the numbers but letters in the names, like a `t` in the first iteration. – Ignatius Reilly Mar 17 '23 at 00:11
  • Your biggest problem is that you're reading the entire data file as a single string, then trying to process it one character at a time. So `data[0]` is `'S'` and `data[1]` is `'t'`. So you print `S : t`, but then you call `float(data[1])`, which is just `float('t')`. Do you see why this doesn't work? You should have been able to determine all of this yourself. Hint: Try printing `data[0]` and `data[1]`. This would have been immediately obvious. – Tom Karzes Mar 17 '23 at 00:19
  • To fix it, you need to break the input into lines, which you can do by using `readlines()` rather than `read()`. Then you need to split each line into words, which you can do with the `split()` method. The, for each line, index 0 with give the first word and index 1 will give the second. – Tom Karzes Mar 17 '23 at 00:20
  • I can't think of a good way to solve this without regex. Is that what your teacher expects, or is it a bit overkill for a beginner exercise? – Felix Fourcolor Mar 17 '23 at 00:36

1 Answers1

1

The trickiest part of this exercise is that we have to parse a string containing both a student name and their marks, but we don't know how long their name is and how many marks they have.

The most natural solution is using regex, which I have mentioned in the comment. But I think it's probably not what the exercise is expecting.

So here's one way to do without it:

  1. Iterate through each line of the file.
  2. Iterate through each word of the line.
  3. Check if it's possible to convert it into a float.
  4. If yes, append it to marks.
  5. Else, add it to the students name
with open(fname, 'r') as f:
    for line in f:
        words = line.split()
        names = []
        marks = []
        for word in words:
            try:
                value = float(word)
            except ValueError:
                names.append(word)
            else:
                marks.append(value)

        # turn the list of names into
        # a string separated by spaces
        name = ' '.join(names)

        if not marks:
            # when there are no numbers on the line,
            # as is the case for the first line,
            # simply ignore
            pass
        else:
            # print out the information as required
            # this part should be easy, I leave it to you
Felix Fourcolor
  • 320
  • 2
  • 8