【问题标题】:python adds extra blank line when writing to CSVpython在写入CSV时添加了额外的空白行
【发布时间】:2020-04-07 04:35:38
【问题描述】:

所以我和一个朋友正在用 python 开发一个游戏。但是,当我们将代码写入排行榜时,存储为 csv 文件类型的外部文件,它似乎总是在输入之间添加一个空行。

代码如下:

def leaderBoardWrite(winnerName,winnerScore):
    with open('leaderboard.csv', mode='a') as leaderboard:
        winnerScoreSort = "{:03d}".format(winnerScore)
        print(winnerScoreSort)
        leaderboardWrite = csv.writer(leaderboard, delimiter=',')
        leaderboardWrite.writerow([winnerScoreSort,winnerName]) ## This writes over the leaderboard, adding the newest score into it.
    leaderBoardRead()

有什么建议吗?

谢谢,

编辑:由于有些人想要更广泛的代码规范,我将快速转发所有内容,以便您拥有重现代码的完整方法

## This is the start of the Dice game, look below at all of the comments to see what I have done once I have coded it.
## The next lines of code import all the nessasory modules for the program to run.
## The CSV Module is for the scoreboard
## Time is for the delays
## Random is for the
## Os is to clear the shell once the program has runself.
import csv,time,random,os
Complete = False ## Sets complete to false because the game has not begun
rounds = 0 ## Sets the rounds to 0 becasue game has not begun
playerOneScore = 000 ## Sets the player one score to 0 because they have not stated scoring yet
playerTwoScore = 000 ## Sets the player two score to 0 because they have not stated scoring yet
dice = [1,2,3,4,5,6] ## All the possible dice numbers
print("""
__          __  _                            _    _               _
\ \        / / | |                          | |  | |             | |
 \ \  /\  / /__| | ___ ___  _ __ ___   ___  | |  | |___  ___ _ __| |
  \ \/  \/ / _ \ |/ __/ _ \| '_ ` _ \ / _ \ | |  | / __|/ _ \ '__| |
   \  /\  /  __/ | (_| (_) | | | | | |  __/ | |__| \__ \  __/ |  |_|
    \/  \/ \___|_|\___\___/|_| |_| |_|\___|  \____/|___/\___|_|  (_) V.1.0.2
""")
time.sleep(1) ##Delay between welcome user and rules
print ("Welcome to my dice game! It is very simple to start playing.\nInput your username and password that were given to you and then type yes to verify you want to play (Please note 2 users both need to do this)\nBoth players will roll the dice twice\nThe totals of the rolls will be added to your net score\nIf your total is ODD, you will lose 5 points off of your overall score\nIf your total is EVEN, you will gain 10 points!\nIf you roll a double, the game will re-roll for you and you will gain the number of points rolled added to your score.\nThe winner is the person who has the most points at the end of the 5 rounds, once you have finished playing, you can see a leaderboard of players who have scored the most points.\nHave fun and good luck!")##Rules will be shown once at the start, straight after rules it will show the time delay.
print ("") ## Space between rules and dice delay
time.sleep(1) ## Delay between rules and dice delay
def PlayerOne(userOneName,playerOneScore,dice,delay): ## The function for Player One to start rolling and scoring
    input("[{}] When you are ready, press the ENTER key to roll the dice!".format(userOneName))
    diceOneRoll = dice[random.randint(0,len(dice)-1)] ## Rolls the first dice
    diceTwoRoll = dice[random.randint(0,len(dice)-1)] ## Rols the seccond dice
    total = diceOneRoll + diceTwoRoll ## Adds the scores from both dice rolls together
    if diceOneRoll == diceTwoRoll: ## Checks if both os the dice rolls were the same
        print("[{}] You have rolled a double, you get another roll!".format(userOneName))
        temp = PlayerOneReRoll(userOneName,dice) ## Calls a function to roll an extra die
        print("[{}] You scored {} from the reroll".format(userOneName,temp))
        playerOneScoreReturn = total + temp ## Adds the score of the reroll to their total score
    elif total % 2 == 0: ## Checks if the total of the two dice is even
        print("[{}] Your total was even, take an extra 10 points".format(userOneName))
        playerOneScoreReturn = total + 10
        pass
    elif total % 2 ==1: ## Checks if the total of the two dice is odd
        print("[{}] You have scored an odd number, you lose 5 points".format(userOneName))
        if playerOneScore-5 <0:
            playerOneScoreReturn = 0
        else:
            playerOneScoreReturn = -5

    else:
        pass
    time.sleep(delay)
    print("[{}] You scored {}".format(userOneName,total))
    time.sleep(delay)
    print("[{}] Your total score is {}".format(userOneName,playerOneScore+playerOneScoreReturn))
    return playerOneScoreReturn

def PlayerTwo(userTwoName,playerTwoScore,dice,delay):
    input("\n[{}] When you are ready, press the ENTER key to roll the dice!".format(userTwoName))
    diceOneRoll = dice[random.randint(0,len(dice)-1)]
    diceTwoRoll = dice[random.randint(0,len(dice)-1)]
    total = diceOneRoll + diceTwoRoll
    if diceOneRoll == diceTwoRoll:
        print("[{}] You have rolled a double, you get another roll!".format(userTwoName))
        temp = PlayerTwoReRoll(userTwoName,dice)
        print("[{}] You scored {} from the reroll".format(userTwoName,temp))
        playerTwoScoreReturn = total + temp
    elif total % 2 == 0:
        print("[{}] Your total was even, take an extra 10 points".format(userTwoName))
        playerTwoScoreReturn = total + 10
        pass
    elif total % 2 ==1:
        print("[{}] You have scored an odd number, you lose 5 points".format(userTwoName))
        if playerTwoScore-5 <0:
            playerTwoScoreReturn = 0
        else:
            playerTwoScoreReturn = -5
    else:
        pass
    time.sleep(delay)
    print("[{}] You scored {}".format(userTwoName,total))
    time.sleep(delay)
    print("[{}] Your total score is {}".format(userTwoName,playerTwoScore+playerTwoScoreReturn))
    return playerTwoScoreReturn

def PlayerOneReRoll(userOneName,dice):
    input("[{}] Ready to roll the dice again? Press ENTER key to roll.".format(userOneName))
    diceOneRoll = dice[random.randint(0,len(dice)-1)]
    total = diceOneRoll
    return total

def PlayerTwoReRoll(userTwoName,dice):
    input("[{}] ".format(userTwoName))
    diceOneRoll = dice[random.randint(0,len(dice)-1)]
    total = diceOneRoll
    return total

def main(userOneName,userTwoName,rounds,playerOneScore,playerTwoScore,Complete):
    print("\nRound [{}/5]\n".format(rounds))
    playerOneScoreTemp = PlayerOne(userOneName,playerOneScore,dice,delay)
    playerTwoScoreTemp = PlayerTwo(userTwoName,playerTwoScore,dice,delay)
    return playerOneScoreTemp,playerTwoScoreTemp

def draw(userOneName,userTwoName,dice,Complete):
    print("draw")
    playerOneScoreTemp = PlayerOneReRoll(userOneName,dice)
    playerTwoScoreTemp = PlayerTwoReRoll(userTwoName,dice)
    print("p1 = ",playerOneScoreTemp,"p2 = ",playerTwoScoreTemp)
    checkForWinner(userOneName,userTwoName,Complete,playerOneScoreTemp,playerTwoScoreTemp)

def checkForWinner(userOneName,userTwoName,Complete,playerOneScore,playerTwoScore):
    if Complete == True:
        if playerOneScore > playerTwoScore:
            print("\n[{}] You win with a score of {}. Well done".format(userOneName,playerOneScore))
            tmp = playerOneScore
            leaderBoardWrite(userOneName,tmp)
        elif playerTwoScore > playerOneScore:
            print("\n[{}] You win with a score of {}. Well done".format(userTwoName,playerTwoScore))
            tmp = playerTwoScore
            leaderBoardWrite(userTwoName,tmp)
        elif playerOneScore == playerTwoScore:
            print("\n[Both] It's come to a draw, play one last round to see who the ultimate champion is!" )
            draw(userOneName,userTwoName,dice,Complete)
        else:
            pass
    else:
        pass

def leaderBoardWrite(winnerName,winnerScore):
    with open('leaderboard.csv', mode='a') as leaderboard:
        winnerScoreSort = "{:03d}".format(winnerScore)
        leaderboardWrite = csv.writer(leaderboard, delimiter=',')
        leaderboardWrite.writerow([winnerScoreSort,winnerName]) ## This writes over the leaderboard, adding the newest score into it.
    leaderBoardRead()

def leaderBoardRead():## Shows the ASCII text of "Leaderboard"
    print (""" 
 _      ______          _____  ______ _____  ____   ____          _____  _____  
| |    |  ____|   /\   |  __ \|  ____|  __ \|  _ \ / __ \   /\   |  __ \|  __ \ 
| |    | |__     /  \  | |  | | |__  | |__) | |_) | |  | | /  \  | |__) | |  | |
| |    |  __|   / /\ \ | |  | |  __| |  _  /|  _ <| |  | |/ /\ \ |  _  /| |  | |
| |____| |____ / ____ \| |__| | |____| | \ \| |_) | |__| / ____ \| | \ \| |__| |
|______|______/_/    \_\_____/|______|_|  \_\____/ \____/_/    \_\_|  \_\_____/
""")
    data = open('leaderboard.csv')
    for row in sorted(csv.reader(data)):
        print(row) ## This reads the leaderboard and allows it to be shown in the code

delay = int(input("Please input a time delay for the dice to roll?\n: "))

## User One Authorisation
with open("logins.csv", newline= '') as csvnames:
    authentication = csv.reader(csvnames, delimiter=",")
    logins = list(authentication)

while True:
    print("Welcome user one!")
    userNameInput = input("Please input your username? \n: ")
    userPasswordInput = input("Please input your password? \n: ")

    for i in range(len(logins)):
        if userNameInput == logins[i][0] and userPasswordInput == logins[i][1]:
            userOneName = logins[i][0]
            userOneAuthorised = True
            break
        else:
            userOneAuthorised = False

    if userOneAuthorised == False:
        print("Sorry {}, you aren't authorised so run this task! \nPlease contact your System Administrator".format(userNameInput))
    else:
        try:
            ready = input("Welcome {}, you have been Authorised. Are you ready to play? (Please type **yes** or **no**) \n:_ ".format(userOneName))
            if ready[0].lower() == "y":
                userOneAuthorised = True
                break
            else:
                print("Please come back later, the game will be waiting for you!")
        except:
            pass

## User Two Authorisation
while True:
    print("Welcome user 2!")
    userNameInput = input("What is your username? \n: ")
    userPasswordInput = input("What is your password? \n: ")

    for i in range(len(logins)):
        if userNameInput == logins[i][0] and userPasswordInput == logins[i][1]:
            userTwoName = logins[i][0]
            userTwoAuthorised = True
            break
        else:
            userTwoAuthorised = False

    if userTwoAuthorised == False:
        print("Sorry {}, you aren't authorised so run this task! \nPlease contact your System Administrator".format(userNameInput))
    else:
        ready = input("Welcome {}, you have been Authorised. Are you ready to play? (Please type **yes** or **no**) \n:_ ".format(userTwoName))
        try:
            if ready[0].lower() == "y":
                userTwoAuthorised = True
                break
            else:
                print("Please come back later, the game will be waiting for you!")
        except:
            pass



if userOneAuthorised == True and userTwoAuthorised == True:
    print("Starting")
    for i in range(1,6):
        roundNums = main(userOneName,userTwoName,i,playerOneScore,playerTwoScore,Complete)
        playerOneScore+=roundNums[0]
        playerTwoScore+=roundNums[1]
        if i == 5:
            Complete = True
        else:
            pass
        checkForWinner(userOneName,userTwoName,Complete,playerOneScore,playerTwoScore)
else:
    pass

time.sleep(4)

抱歉,顺序太尴尬了,我的朋友似乎喜欢点有趣的东西。 感谢您迄今为止的所有建议。

【问题讨论】:

  • 您正在为每一行创建一个新的csv.writer。这可能是问题所在。
  • 这能回答你的问题吗? How can I remove a trailing newline?
  • 你能分享更多你的节目吗?我想看看更广泛的设计,并能够运行它(参见:minimal reproducible example)。此外,变量和函数名称应遵循lower_case_with_underscores 样式。
  • 顺便说一句,这不是一个空白行。那是一个没有数据的空 CSV 行/行,对吧?最后,请将数据/代码作为帖子本身的文本分享,而不是图片。
  • 这能回答你的问题吗? csv.writerows() puts newline after each row

标签: python csv file-writing


【解决方案1】:

我之前也遇到过同样的问题。我最后写了一个宏来删除空白行。我建议将每行所需的所有详细信息放入地图中,将地图附加到列表中,然后使用 pandas 将地图列表转换为数据框。然后使用 df.to_csv(filename) 函数将其粘贴到电子表格中。

如果您需要不断地追加到电子表格,那么您所要做的就是使用 pandas.read_csv(filename) 读取 csv,创建上面的数据框,追加到您当前拥有的内容,然后使用 to_csv。您唯一需要确保的是 to_csv 在打印时添加了一个索引列,因此请确保在附加之前将数据框减少为仅需要的列。它不会破坏任何东西,但会使存储在电子表格中的数据变得更加混乱。

祝你好运!

【讨论】:

  • 我会这样做,但不幸的是,由于我的编码方式,我无法安装诸如 pandas 之类的奖励模块。这是关于代码的事情之一。我们只能使用基本模块。