开发者

Stuck in a while loop, can you please help?

I am currently writing a program that reads records from a txt file and prints the data on the screen as such:

                       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 LITERATUR开发者_Go百科E                  D
                    INTRO. TO BUSINESS                  B
                    Total courses taken = 4

Total courses taken by all students = 11

Run complete.  Press the Enter key to exit.

This is the text file it reads 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

Here is my code:

# VARIABLE DEFINITIONS

name = ""
course = ""
grade = ""
recordCount = 0
eof = False
gradeFile = ""

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

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

def startUp():
    global gradeFile
    gradeFile = open("grades.txt","r")
    print ("grade report\n").center(60).upper()
    print "name".upper(),"course".rjust(22).upper(),"grade".rjust(32).upper()
    print "-" * 60
    readRecord()

def readRecord():
    global name, course, grade

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

def processRecords():
    numOfRecs = 0
    while not eof:
        numOfRecs += 1
        printLine()
        readRecord()
    return numOfRecs

def printLine():
    print name, course.rjust(3), grade.rjust(3)

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

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

startUp()
recordCount = processRecords()
closeUp()

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

The results just print the very last line of the txt file and is stuck in a loop. Any assistance would be greatly appreciated. Thank you for your time.


Why don't you do it all in a single function -

def processRecords():
    print ("grade report\n").center(60).upper()
    print "name".upper(),"course".rjust(22).upper(),"grade".rjust(32).upper()
    print "-" * 60

    rec_count = 0
    for line in open("grades.txt","r"):
        name   = line[0:20]
        course = line[20:50]
        grade  = line[50:51]
        print name, course.rjust(3), grade.rjust(3)
        rec_count += 1
    return rec_count

All those functions compressed in this one single function. You seem to be programming much like C code. This is Python!

Also try to avoid using globals unless you must. Just a principle I follow. Clearly in this situation you don't need to.


You have to declare eof as global in readRecord():

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

Otherwise, the changes you make to eof when studentRecord is empty won't survive outside readRecord()'s scope .


In this design, "eof" needs to be addded to the globals list in readRecord()

Otherwise assigning it creates a new local variable, which processRecords() never sees.


You need to add eof to the global variables in readRecord():

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

But your solution is a bit un-pythonic. How about something shorter and more flexible:

import re
print ("grade report\n").center(60).upper()
print "name".upper(),"course".rjust(22).upper(),"grade".rjust(32).upper()
print "-" * 60
for line in open("grades.txt"):
    name, course, grade = re.split("   *", line.strip())
    print "%-21s%-34s%-21s" % (name, course, grade)

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

The regular expression is a very simple one that splits on multiple spaces. If you delimiter is something else, then replace the regular expression " *" with your delimiter.

And here is a version that uses python dicts to track the courses and grades by student (i.e. your target output):

import re

print ("grade report\n").center(60).upper()
print "name".upper(),"course".rjust(22).upper(),"grade".rjust(32).upper()
print "-" * 60
grades = {}
total_courses = 0
for line in open("grades.txt"):
    name, course, grade = re.split("   *", line.strip())
    if not grades.get(name): grades[name] = []
    grades[name].append([course, grade])

for name, data in grades.items():
    for course, grade in data:
        print "%-21s%-34s%s" % (name, course, grade)
        name = ""
    print "%-21sTotal courses taken = %d\n" % (" ", len(data))
    total_courses += len(data)

print "Total courses taken by all students = %d" % total_courses

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

BTW, it sounds like you need to learn more about python (and the python way of programming). I recommend Dive Into Python. IMO it's the fastest (and most entertaining) way to come up to speed in python if you are have some programming experience.


You're missing a global here, while your while loop checks the global variable eof, your readRecord function does in fact set the local variable eof.


You have to add eof in the list of globals in readRecord.

However, you said any help, so here's another version:

import itertools as it, operator as op
import collections

Record= collections.namedtuple("Record", "name course grade")
grouper= op.itemgetter(0) # or op.attrgetter('name')

def file_reader(fobj_in):
    for line in fobj_in:
        name= line[:20].rstrip()
        course= line[20:50].rstrip()
        grade= line[50:].rstrip()
        yield Record(name, course, grade)

def process(fn_in, fobj_out):
    for name, records in it.groupby(file_reader(fobj_in), grouper):
        out_name= name
        for index, record in enumerate(records, 1):
            fobj_out.write(
                "%-20.19s%-36.35s%s\n" % (out_name, record.course, record.grade)
            )
            out_name= ''
        fobj_out.write("%20sTotal courses taken = %d\n" % ('', index))

if __name__ == "__main__":
    import sys

    with open('so4009899.txt', 'r') as fobj_in:
        process(fobj_in, sys.stdout)


If you have to use many functions for the purposes of 'structure', consider passing parameters to the functions instead of using globals. Here is a small change that illustrates my meaning.

def startUp():
    print ("grade report\n").center(60).upper()
    print "name".upper(),"course".rjust(22).upper(),"grade".rjust(32).upper()
    print "-" * 60
    processRecords()

def processRecords():
    numOfRecs = 0
    for line in open("grades.txt","r"):
        numOfRecs += 1
        printLine(line)
    return numOfRecs

def printLine(studentRecord):
    name = studentRecord[0:20]
    course = studentRecord[20:50]
    grade = studentRecord[50:51]
    print name, course.rjust(3), grade.rjust(3)

def closeUp(recordCount):
    print "\nTotal courses taken by all students = ",recordCount


startUp()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜