-1

Completely stuck on functions....

I have a .txt file:

Bronson 90 85 75 76 
Conor 90 90 90 90
Austyn 50 55 32 75
Mark 96 95 85 85
Anthony 85 85 85 85 

And I'm trying to take this code (below). And turn it into functions to produce the same output:

with open(argv[1]) as f:
     names = []
     for line in f:
        names.append(line.split()[0])
        print('\nNames of students who have written tests:')
        print(*sorted(names), sep=' ')

# prompt user to input which student you want to view
      name = input('Enter name of student whose test results '
                     'you wish to see: ')
      if name not in names:
          print('\nNo test data found for ', name)
          input("Press Enter to continue ...")
      else:
          name_print = "\nSummary of Test Results for " + name

# print test scores of the student selected
      with open(argv[1]) as f:
          for line in f:
              parts = line.split()
              if parts[0] == name:
                  print(name_print)
                  print('=' * ((len(name_print)) - 1))
                  test_scores = ' '.join(parts[1:])
                  print('Test scores: ', end=' ')
                  print(test_scores)

Currently outputs:

Names of students who have written tests:
Anthony Austyn Bronson Conor Mark
Enter name of student whose test results you wish to see: Anthony

Summary of Test Results for Anthony
===================================
Test scores:  85 85 85 85
Number of tests written ..................  4

I want to make it run on one main() module using process_marks(f):

from functions import process_marks 

def main():
    try:
        f = open(argv[1])
    except FileNotFoundError:
        print("\nFile ", argv[1], "is not available")
        exit()
    process_marks(f). #The program essentially runs in this function with help from helpers
    f.close()

main()

This is what I currently have:

def process_marks(f):
        names = []
        for line in f:
            names.append(line.split()[0])
        print('\nNames of students who have written tests:')
        names = sorted(names)
        print(*names, sep=' ')
        name = input('Enter name of student whose test results '
                     'you wish to see: ')
        check_name(name, names)
        print_grades(name, line)

def check_name(name, names):
    if name not in names:
        print('\nNo test data found for ', name)
        input("Press Enter to continue ...")
    else:
        name_print = "\nSummary of Test Results for " + name
        print(name_print)
        print('=' * ((len(name_print)) - 1))

def print_grades(name, line):
    test_scores = ' '.join(line[1:])
    print('Test scores: ', end=' ')
    print(test_scores)

This is what outputs using above code:

Names of students who have written tests:
Anthony Austyn Bronson Conor Mark
Enter name of student whose test results you wish to see: Mark

Summary of Test Results for Mark
================================
Test scores:  n t h o n y   8 5   8 5   8 5   8 5

I don't want to go to far away from the current code I have (i want to use lists etc because id like to eventually include averages, max, min etc. However, I have been grinding over this for a while having obvious problems getting the code to access the line that corresponds to the name.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Gizmo
  • 21
  • 1
  • 1
  • 8
  • The problem is in the function process_marks. You pass line to the function print_grades , when its value equals the last row of the txt file. – Levkovich Efrat Feb 29 '20 at 20:35
  • Please don't post the same question in different variations many times. You have already asked the exact question here: https://stackoverflow.com/questions/60468330/creating-a-function-to-process-through-a-txt-file-of-student-grades/60468700#60468700 – Tomerikoo Feb 29 '20 at 23:04

1 Answers1

1

Your method-breakdown is a bit off.

For example this line:

print_grades(name, line)

Will use the last value of line from the for loop above. Which will always be "Anthony"

You can try to pass the values from method to method as below:

from sys import argv


def get_names(my_file):
    names = []
    for line in my_file:
        names.append(line.split()[0])
        print('\nNames of students who have written tests:')
        print(*sorted(names), sep=' ')
    return names


def get_and_check_name(names):
    name = input('Enter name of student whose test results '
                 'you wish to see: ')
    if name not in names:
        print('\nNo test data found for ', name)
        input("Press Enter to continue ...")
    else:
        name_print = "\nSummary of Test Results for " + name
        return name, name_print


def print_scores(f, name, name_print):
    for line in f:
        parts = line.split()
        if parts[0] == name:
            print(name_print)
            print('=' * ((len(name_print)) - 1))
            test_scores = ' '.join(parts[1:])
            print('Test scores: ', end=' ')
            print(test_scores)


def process_marks(f):
    While True:
        names = get_names(f)
        name, name_print = get_and_check_name(names)
        f.seek(0)
        print_scores(f, name, name_print)
        yes_no = input('\nDo again for another student?')
        if yes_no == 'n':
            break
        continue 

with open(argv[1]) as f:
    process_marks(f)
Gizmo
  • 21
  • 1
  • 1
  • 8
rdas
  • 20,604
  • 6
  • 33
  • 46
  • Works for me. Please make sure you use the code I provided in the answer. – rdas Feb 29 '20 at 20:51
  • I feel like i'm very close.... I don't know if it would affect but I'm importing this functions module into a main() like in my original post. in the main() its being called with a try: f = open(argv[1] – Gizmo Feb 29 '20 at 20:56
  • in print_scores() for line in f: nameError: name 'f' is not defined. The program does everything else up until print_scores – Gizmo Feb 29 '20 at 21:03
  • Fixed, do check – rdas Feb 29 '20 at 21:05
  • This is great. So basically where i was going wrong was that i wasnt taking the values from previous methods and passing them into the next correctly ?? – Gizmo Feb 29 '20 at 21:09
  • Yeah. The methods were using values from the outer scope which may cause unexpected bahaviour. – rdas Feb 29 '20 at 21:13
  • Ok cool thanks. One more quick question. I want to wrap the whole thing in a While True loop. So it loops through until user enters n. This is what i have (which loops through as wanted. However, it doesn't take in the list of names the second time through. See edit – Gizmo Feb 29 '20 at 21:34
  • Check this: https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response – rdas Feb 29 '20 at 21:35