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()
加载中,请稍侯......
精彩评论