陷入困境,你可以帮忙吗?

时间:2010-10-24 19:08:28

标签: python variable-assignment

我目前正在编写一个从txt文件中读取记录的程序,并在屏幕上打印数据:

                       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.

这是从中读取的文本文件:

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

这是我的代码:

# 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.")

结果只是打印txt文件的最后一行并且卡在一个循环中。任何帮助将不胜感激。谢谢你的时间。

7 个答案:

答案 0 :(得分:5)

为什么不在一个功能中完成所有操作 -

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

在这一个单一功能中压缩所有这些功能。你似乎编程很像C代码。这是Python!

除非必须,否则尽量避免使用globals。只是我遵循的原则。显然,在这种情况下你不需要。

答案 1 :(得分:4)

您必须在eof中将global声明为readRecord()

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

否则,当eof为空时,您对studentRecord所做的更改将无法在readRecord()范围之外生效。

答案 2 :(得分:3)

在此设计中,需要将“eof”添加到readRecord()

中的全局列表中

否则分配它会创建一个新的局部变量,进程Records()永远不会看到。

答案 3 :(得分:3)

您需要在readRecord()中添加eof到全局变量:

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

但是你的解决方案有点不像pythonic。更简短,更灵活的事情:

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.")

正则表达式是一个非常简单的表达式,可以分割多个空格。如果您的分隔符是其他内容,则将正则表达式" *"替换为分隔符。

这是一个使用python dicts跟踪学生的课程和成绩的版本(即你的目标输出):

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.")
顺便说一句,听起来你需要了解更多关于python (以及python的编程方式)。我推荐Dive Into Python。如果你有一些编程经验,IMO是最快(也是最有趣)的方法来加速python。

答案 4 :(得分:2)

你在这里错过global,而你的while循环检查全局变量eof,你的readRecord函数确实设置了local变量{{1 }}

答案 5 :(得分:2)

您必须在eof中的全局变量列表中添加readRecord

但是,您说任何帮助,所以这是另一个版本:

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)

答案 6 :(得分:1)

如果 为了'结构'而使用许多函数,请考虑将参数传递给函数而不是使用全局变量。这是一个小小的变化,说明了我的意思。

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()