views:

86

answers:

3

Hello all! Thanks for viewing my question and thanks in advance for any help you may provide. I am writing a program that reads lines from a txt file and then prints the output in a certain fashion. Here they both are

Here is the txt file I am reading from

JOE FRITZ           AMERICAN GOVERNMENT           B
JOE FRITZ           CALCULUS I                    A
JOE FRITZ           COMPUTER PROGRAMMING          B
JOE FRITZ           ENGLISH COMPOSITION           A
LANE SMITH          FUND. OF DATA PROCESSING      B
LANE SMITH          INTERMEDIATE SWIMMING         A
LANE SMITH          INTRO. TO BUSINESS            C
JOHN SPITZ          CHOIR                         C
JOHN SPITZ          COLLEGE STATISTICS            B
JOHN SPITZ          ENGLISH LITERATURE            D
JOHN SPITZ          INTRO. TO BUSINESS            B

I am trying to get my output to look like this:

                       GRADE REPORT

NAME                COURSE                            GRADE
-----------------------------------------------------------
JOE FRITZ           AMERICAN GOVERNMENT                 B
                    CALCULUS I                          A
                    COMPUTER PROGRAMMING                B
                    ENGLISH COMPOSITION                 A
                    Total courses taken = 4

LANE SMITH          FUND. OF DATA PROCESSING            B
                    INTERMEDIATE SWIMMING               A
                    INTRO. TO BUSINESS                  C
                    Total courses taken = 3

JOHN SPITZ          CHOIR                               C
                    COLLEGE STATISTICS                  B
                    ENGLISH LITERATURE                  D
                    INTRO. TO BUSINESS                  B
                    Total courses taken = 4

Total courses taken by all students = 11

Run complete.  Press the Enter key to exit.

EDIT

Thanks to your help, I finished this program.

I know it may be ugly, but ATM I am just happy to have the output right.

Here is the source that will display the correct output:

#-----------------------------------------------------------------------
# VARIABLE DEFINITIONS

name = ""
previousName = ""
course = ""
grade = ""
grandTotal = 0
courseCount = 0
eof = False

#-----------------------------------------------------------------------
# CONSTANT DEFINITIONS

#-----------------------------------------------------------------------
# FUNCTION DEFINITIONS

def startUp():
    global gradeFile, grandTotal,courseCount, previousName, name
    grandTotal = 0
    courseCount = 0
    gradeFile = open("grades.txt","r")
    print
    print ("grade report\n").center(60).upper()
    print "name".upper(),"course".rjust(21).upper(),"grade".rjust(33).upper()
    print "-" * 60
    readRecord()


def readRecord():
    global name, course, grade, eof, courseCount

    studentRecord = gradeFile.readline()
    if studentRecord == "":
        eof = True
    else:
        name = studentRecord[0:20]
        course = studentRecord[20:50]
        grade = studentRecord[50:51]
        eof = False

def processRecords():
    global courseCount, previousName, name, grandTotal
    while not eof:
        if name != previousName:
            if name == "JOE FRITZ           ":
                courseCount = 0
                print name + course + "       " + grade
                previousName = name
                courseCount += 1
            else:
                print "\t\t    Total courses taken =",courseCount 
                print
                courseCount = 0
                print name + course + "       " + grade
                previousName = name
                courseCount += 1
        else:
            print (" " * 20) + course + "       " + grade
            courseCount += 1
        grandTotal +=1
        readRecord()
    print "\t\t    Total courses taken =",courseCount


def closeUp():
    gradeFile.close()
    print "\nTotal courses taken by all students =",grandTotal

#-----------------------------------------------------------------------
# PROGRAM'S MAIN LOGIC

startUp()
processRecords()
closeUp()

raw_input("\nRun complete. Press the Enter key to exit.")

Thanks for your help everyone. I really do appreciate it. Sorry if I have frustrated anyone during the process. Have a good one. Peace

+3  A: 

i just figure it out one of the bugs in your code in the function readRecord() you are just reading the first line of your file just it ; you should loop over all lines or make readRecord() a generator .

  def readRecord():
     global name, course, grade, eof

     studentRecord = gradeFile.readline()  # <----- HERE

     if studentRecord == "":
        eof = True
     else:
        name = studentRecord[0:20]
        course = studentRecord[20:50]
        grade = studentRecord[50:51]
        eof = False

but despite this , to be sincere i don't like your code much, here is what i will do if i were you:

1) get data from file by any way (csv, regex ...) ; i think we have already the answer in here

2) put the data in a dictionary or whatever (so you can manipulate them as you wich).

3) use itertools.groupby() to group by student and to calculate the sum of what you want.

4) use string Template(), because maybe the format will change, and don't hard code the format of your output like you did.

And please test yours function one by one after write in them , because if you don't it will be hard to figure out which part of the code is not working.

EDIT:

and i will not ask you why you want to do this, because if you want to put them in a file again you will have the same problem as before if you want to retrieve them again, and if you objective is just to make a beautiful output i will ask you is it worth it ?

One last advise use a well know format like csv, xml ...

And Good luck :)

singularity
thanks. The thing is that my instructor wants me to use this structure with the multiple functions. Sorry that my code sucks, but I am trying. Thanks for the response
eleven357
thanks for the advice
eleven357
@elevendub : always this teachers with there stupid exercises , but what the hell , you could change the function readRecord() like i told you , if you don't figure this out , please let us know :)
singularity
So I should use read() instead of readline()?
eleven357
@elevendub: no the readline() is working fine here, just get the data first from the file and put it in a dictionary then do what ever you want with it;
singularity
@singularity: -1 (1) "get data from file by any way (csv, regex ...)" -- totally irrelevant to reading a fixed-field-width record format (2) "you are just reading the first line of your file just it " -- so how come other records from the file show up in the output? +1 (3) itertools.groupby (4) string.Template
John Machin
A: 

string formatting would greatly clean up your output code, since it would let you express the justification in a much more concise way.

Skurmedel
Thanks for pointing that out. I appreciate it.
eleven357
-1 `print "a", "b", "c"` -> `a b c\n` -- April Fools Day? Full moon?
John Machin
John Machin: Late night, long time since Python 2.7.
Skurmedel
A: 

This may not be the 1960s COBOLlocks way that your benighted instructor wants you to do it, but the general ideas are:

(1) itertools.groupby can save you all that previous/current detecting-name-changed malarky

(2) you should extract your data records into a sensible format up front -- stripping trailing whitespace (always a good idea) gets rid of stray newlines that are not part of the data

(3) global variables used like you are doing are the utter pox (in ANY language).

import itertools

guff = """\
JOE FRITZ           AMERICAN GOVERNMENT           B
JOE FRITZ           CALCULUS I                    A
JOE FRITZ           COMPUTER PROGRAMMING          B
JOE FRITZ           ENGLISH COMPOSITION           A
LANE SMITH          FUND. OF DATA PROCESSING      B
LANE SMITH          INTERMEDIATE SWIMMING         A
LANE SMITH          INTRO. TO BUSINESS            C
JOHN SPITZ          CHOIR                         C
JOHN SPITZ          COLLEGE STATISTICS            B
JOHN SPITZ          ENGLISH LITERATURE            D
JOHN SPITZ          INTRO. TO BUSINESS            B
"""

data_source = guff.splitlines(True) # simulate file

columns = (slice(0, 20), slice(20, 50), slice(50, 51))

def data_reader(raw_record_iterator):
    for line in raw_record_iterator:
        yield [line[sl].rstrip() for sl in columns]

def process_file():

    # f = open('my_file.text', 'r')
    # or use a 'with' statement
    # data_source = f

    for key, grouper in itertools.groupby(
            data_reader(data_source), lambda element: element[0]):
        print "=== start student %s ===" % key
        for cooked_record in grouper:
            print cooked_record
        print "=== end student %s ===" % key
    print "=== Grand totals here ==="
    # f.close()

if __name__ == "__main__":
    process_file()

actual output:

=== start student JOE FRITZ ===
['JOE FRITZ', 'AMERICAN GOVERNMENT', 'B']
['JOE FRITZ', 'CALCULUS I', 'A']
['JOE FRITZ', 'COMPUTER PROGRAMMING', 'B']
['JOE FRITZ', 'ENGLISH COMPOSITION', 'A']
=== end student JOE FRITZ ===
=== start student LANE SMITH ===
['LANE SMITH', 'FUND. OF DATA PROCESSING', 'B']
['LANE SMITH', 'INTERMEDIATE SWIMMING', 'A']
['LANE SMITH', 'INTRO. TO BUSINESS', 'C']
=== end student LANE SMITH ===
=== start student JOHN SPITZ ===
['JOHN SPITZ', 'CHOIR', 'C']
['JOHN SPITZ', 'COLLEGE STATISTICS', 'B']
['JOHN SPITZ', 'ENGLISH LITERATURE', 'D']
['JOHN SPITZ', 'INTRO. TO BUSINESS', 'B']
=== end student JOHN SPITZ ===
=== Grand totals here ===
John Machin
Thanks for the response, sorry for the frustration.
eleven357