【问题标题】:Append to data list write to CSV追加到数据列表写入 CSV
【发布时间】:2014-11-23 04:22:18
【问题描述】:

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

我需要输出看起来像:(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()

【问题讨论】:

  • edit您的问题包括示例输入、您获得的输出、您想要获得的输出以及任何错误或回溯。

标签: python list csv append


【解决方案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. 如果用户已经有了三个分数,我不知道你想做什么(重新开始,从第一个添加的删除,从最后添加的删除(...),所以我没有编码..

编辑以适应新要求:

#!/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()

【讨论】:

  • 优秀。最终,当用户获得三分时,我希望程序重新开始,从第一个分数中删除和替换。任何额外的帮助将不胜感激。
  • 要让用户在文件的相同位置重新开始评分,您只需在此if (if len(record["scores"]) >= MAX_SCORES) 中插入以下内容:actualScoresTable[index]["scores"] = [newScore]
  • 对不起,我没有很好地解释自己。我需要程序继续重写分数(然后一个接一个地替换),以便在任何时候列表都将包含最后 3 个或最新的 3 个分数。再次感谢任何帮助。
  • 所以,例如从Arthur,3,4,7(如果我为亚瑟插入9)到Arthur,4,7,9
  • @learningpython 我用新代码编辑了我的答案以适应这个规则
猜你喜欢
  • 2015-09-08
  • 2017-02-06
  • 2019-04-11
  • 1970-01-01
  • 2015-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多