附加到数据列表写入CSV

时间:2014-09-28 19:17:37

标签: python list csv append

我正在尝试编写一个记录测试最后三次尝试(分数)的程序。用户可以随时重新参加测试,因此程序必须找到用户是否存在并附加用户的最新分数。如果用户不存在,则必须在用户首次尝试时记录用户名。我设法让程序/功能记录用户的第一个分数,但如果用户存在,我很难追加进一步的尝试。我也不知道如何阻止列表增长 - 它应该只记录最后三次尝试 - 进一步的尝试应该重写现有的。如果这是错误的,请原谅我的无知 - 我正在学习。

我需要输出看起来像:(经过3次尝试后,列表需要开始覆盖自己

佛瑞德,18,17,16

保罗,15,12,16

代码并不完全符合我的要求,但我得到的唯一错误是当用户已经存在时:scoresFile.write(line +“\ n”) ValueError:关闭文件的I / O操作

#add score
def main():
    #ask for name and score
    name = input("Please enter the name you wish to add")
    score = input("Please enter the high score")
    message=""

    #open the highscores line and read in all the lines to a list called ScoresList. Then close the file.
    scoresFile = open("highscores.txt","r")
    ScoresList = scoresFile.readlines()
    scoresFile.close()

    #for each line in the ScoresList list
    for i in range(0, len(ScoresList) ):

        #check to see if the name is in the line
        if name in ScoresList[i]:

            #append the score to the end of the list
            ScoresList[i] = (name + (str(score) + ","))

            #write the scores back to the file. Overwrite with the new list
            scoresFile = open("highscores.txt","w")
            for line in ScoresList:
                scoresFile.write(line + "\n")
                scoresFile.close()

            #no need to continue in the loop so break out.
            #break
            else:
                # message as user does not exist
                message = ""

#if message is still blank then it means that the name was not found. Open the
#file for appending and add the new name and score to the end.
    if message=="":
        message = "New score added."
        scoresFile = open("highscores.txt","a")
        scoresFile.write(name + str(score)+"\n")
        scoresFile.close()


    print(message)

main()

1 个答案:

答案 0 :(得分:1)

针对您的问题的一个自我解释的解决方案:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# name,score_1,score_2,score_3
# append score to a user
# |_ if user not exists: add user and new score
# |_ an user can't have more than 3 scores


SCORE_FILENAME  = "highscores.txt"
MAX_SCORES = 3

def getName():
    return raw_input("Please enter the name you wish to add: ").strip()
def getScore():
    return raw_input("Please enter the high score: ").strip()
def log(*msg):
    print "\t[LOG] " + " ".join([word for word in msg])


if __name__ == "__main__":

    # Get new name and Score:
    newName = getName()
    newScore = getScore()
    log("NewUser and NewScore = %s,%s" % (newName,newScore))

    # open file and get actual scores:
    log("Opening score file: %s" % SCORE_FILENAME)
    try: scoresFile = open(SCORE_FILENAME, "r+")
    except IOError: scoresFile = open(SCORE_FILENAME, "w+") # File not exists
    actualScoresTable = []
    for line in scoresFile:
        tmp = line.strip().replace("\n","").split(",")
        actualScoresTable.append({
            "name": tmp[0],
            "scores": tmp[1:],
        })
    scoresFile.close()
    log("Actual score table: %s" % actualScoresTable)

    # update scores or insert new record:
    new = True
    for index, record in enumerate( actualScoresTable ):
        if record["name"] == newName:
            # The user exists in scores table, check how many scores he has:
            if len(record["scores"]) >= MAX_SCORES: 
                # Max. Scores permitted. What to do here?
                log("Actual user '%s' already have %s scores '%s'. What we have to do now?" % (newName, MAX_SCORES, ",".join(record["scores"])))
            else:
                log("Add score '%s' to '%s' that now have [%s]" % (newScore,newName,",".join(record["scores"])))
                actualScoresTable[index]["scores"].append(newScore)
            new = False
            break
    if new:
        log("User '%s' not exists in actual Scores Table. So append it." % newName)
        actualScoresTable.append({
            "name": newName,
            "scores": [newScore],
        })

    # Save result to file and close it:
    scoresFile = open(SCORE_FILENAME, "w+") # Truncating file (write all again)
    for record in actualScoresTable:
        scoresFile.write( "%s,%s\n" % (record["name"], ",".join(record["scores"])) )
    log("Writing changes to file: %s" % actualScoresTable)
    scoresFile.close()

注意:

  1. 有许多不同的更改可以改进此解决方案(使用with在打开的文件中操作,如果是记录更新,则直接写入 - 不截断文件,...)。由于你的昵称:“learningpython”;)
  2. ,我想通过这种方式更加明确
  3. 如果用户已经有三个分数,我不知道你想做什么(重新开始,从第一次添加删除,从上次添加删除(...),所以我没有编码...
  4. 编辑符合新要求:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    # name,score_1,score_2,score_3
    # append score to a user
    # |_ if user not exists: add user and new score
    # |_ an user can't have more than 3 scores
    
    
    SCORE_FILENAME  = "highscores.txt"
    MAX_SCORES = 3
    
    def getName():
        return raw_input("Please enter the name you wish to add: ").strip()
    def getScore():
        return raw_input("Please enter the high score: ").strip()
    def log(*msg):
        print "\t[LOG] " + " ".join([word for word in msg])
    
    
    if __name__ == "__main__":
    
        # Get new name and Score:
        newName = getName()
        newScore = getScore()
        log("NewUser and NewScore = %s,%s" % (newName,newScore))
    
        # open file and get actual scores:
        log("Opening score file: %s" % SCORE_FILENAME)
        try: scoresFile = open(SCORE_FILENAME, "r+")
        except IOError: scoresFile = open(SCORE_FILENAME, "w+") # File not exists
        actualScoresTable = []
        for line in scoresFile:
            tmp = line.strip().replace("\n","").split(",")
            actualScoresTable.append({
                                     "name": tmp[0],
                                     "scores": tmp[1:],
                                     })
        scoresFile.close()
        log("Actual score table: %s" % actualScoresTable)
    
        # update scores or insert new record:
        new = True
        for index, record in enumerate( actualScoresTable ):
            if record["name"] == newName:
                # The user exists in scores table, append new score:
                log("User '%s' exists in actual Scores Table. So append score '%s' to him." % (newName,newScore))
                actualScoresTable[index]["scores"].append(newScore)
                # if now we have more than 3 scores, we delete the first one (the oldest one):
                if len(record["scores"]) > MAX_SCORES:
                    log("User '%s' reached max. scores record history, so append score '%s' to him, and delete the oldest: '%s'" % (newName,newScore,actualScoresTable[index]["scores"][0]))
                    actualScoresTable[index]["scores"].pop(0) # OR del actualScoresTable[index]["scores"][0]
                new = False
                break
        if new:
            log("User '%s' not exists in actual Scores Table. So append it." % newName)
            actualScoresTable.append({
                                     "name": newName,
                                     "scores": [newScore],
                                     })
    
        # Save result to file and close it:
        scoresFile = open(SCORE_FILENAME, "w+") # Truncating file (write all again)
        for record in actualScoresTable:
            scoresFile.write( "%s,%s\n" % (record["name"], ",".join(record["scores"])) )
        log("Writing changes to file: %s" % actualScoresTable)
        scoresFile.close()