my python script prints the same value more times - python

hi guys i made a script for a game in python (the game is written in python too) that logs all users name that joins in game and saves them in a text file so:
def onPlayerJoin(self, player):
'Called for new players joined'
nick= player.getName(full=True).encode('utf-8')
#append
f = open(r"ALLIDS.txt", "a+")
f.seek(0)
data = f.read(100)
if len(data) > 0 :
f.write("\n")
f.write(str(nick)+": ")
IT DOESN'T MAKE ANY BUGz AND IT WORKS WELL
OUTPUT OF TEXT FILE
Linux31748:
JunkieSam:
Linux31748:
JunkieSam:
StratexFsk:
Linux31748:
StratexFsk:
Linux31748:
DrugrichSam:
SapoBully:
Stop Using /GP:
JunkieSam:
it prints the same player name more times so i want to fix that but i don't know how
thanks in advance for the replies , love this community every day more.

You can check if player already written(also I simplified some of the syntax):
def log_player(player_nick, file=r"ALLIDS.txt"):
with open(file, "a+") as f:
f.seek(0)
# TODO: improve algorithm, this is just showing the concept
if player_nick in f.read():
return
f.write(f'{player_nick}\n')
def onPlayerJoin(self, player):
'Called for new players joined'
nick = player.getName(full=True).encode('utf-8')
log_player(nick)
Can you have a try?

Before you write a player's name, you should check whether the name is existed.
Check code:
def is_name_existed(name):
with open(r"test.txt", "r") as f:
lines = f.readlines()
for line in lines:
if line == "{}: \n".format(name) or line == "{}: ".format(name):
return True
return False

Related

Writing into a file Python

I am trying to get user input into a text file on different lines. The user input is stored in a list then the list is appended. I realize you are not suppose to use quotes since that will act as your own input. How could I go about using the user input?
def userfile():
text = []
s1 = input("Enter sentence #1 ")
s1 = input("Enter sentence #2 ")
text.append(s1)
userfile = open(os.path.join(sys.path[0], "sample2.txt"), "w")
lines = ['s1\n', 's1\n']
userfile.writelines(lines)
userfile.close()
newfile = open(os.path.join(sys.path[0],"sample2.txt"), "r")
print(newfile.read())
def main():
#txtfile()
userfile()
if __name__ == "__main__":
main()
I think your error is in userfile(): you write both inputs into the same variable s1. And then you don't even use the text array you just created.
Try this:
def userfile():
text = []
text.append(input("Enter sentence #1 "))
text.append(input("Enter sentence #2 "))
# ...
userfile.writelines(text)
# ...
I think you should just modify your code to lines = [s1+'\n', s1+'\n'] if I Understand your problem.
First your indentation is wrong, and you are using a variable named userfile within a function called userfile() which is confusing but doesn't really matter, finally you are overwriting your s1 variable with the second input.
I also recommend using with when opening a file as that will automatically close the file when finished with it.
def userfile():
text = []
for i in range(1, 3):
text.append(input("Enter sentence #{i} ".format(i)))
with open(os.path.join(sys.path[0], "sample2.txt"), "w") as my_file:
my_file.writelines(text)
with open(os.path.join(sys.path[0],"sample2.txt"), "r") as new_file:
print(new_file.read())
def main():
# txtfile()
userfile()
if __name__ == "__main__":
main()
Also I used a loop for the user input which allows you to require as many inputs from the user as you want by only changing 1 number.

How to check a file to determine if there's a variable in it?

I'm trying to check a file to test if there's a variable in it, but it only seems to believe the variable isn't in the file, even when it is.
I'm trying to check for player1 in the file, LOGINS.txt, and the part where it writes player1 to the file appears to work, but it only seems to return that player1 is not in the file, even when it is. I have tried printing the reading of the file, but it prints a blank line.
D = False
# ^ Main Loop
Q = False
# ^ Sub-loops
while D != True:
player1 = input("What is Player 1's name?\n")
with open("LOGINS.txt", "a+") as f:
w = f.read()
if player1 in w:
print("Authorised")
else:
un_player1 = input("Not currently authorised, would you like to add your name to the list? Y/N.\n")
while Q != True:
if un_player1 == "Y":
f.writelines(str(player1) + "\n")
print("Registered.")
Q = True
else:
print("Bye!")
Q = True
D = True
I didn't close the file at the end because I'm planning to use the opened file for a piece of code straight after.
Thank you everyone for helping me! It's working now and I'm very grateful
On the line
with open("LOGINS.txt", "a+") as f:
your using "a+" mode for your file reader. As Mahrkeenerh pointed out this places your pointer at the end of the file, so when you go to read, the string is empty and you get False.
Mahrkeenerh just beat me with his comment, but the solution to this is using f.seek(0) to move your pointer back to the start of the file, or if you know where the variable your looking for is you can set it to that point.

Trying to load and edit a pickled dictionary, getting an EOFError

I'm trying to modify a trivia program found in a book as part of a tutorial; I need to save the name and score of the player using a pickled dictionary. I've already created the dat file using a separate program, to avoid reading from a file that doesn't exist.
This is the code for the trivia program.
#Trivia Challenge
#Trivia game that reads a plain text file
import sys
def open_file(file_name, mode):
"""Open a file"""
try:
the_file = open(file_name, mode)
except IOError as e:
print("Unable to open the file", file_name, "Ending program.\n", e)
input("\n\nPress the enter key to exit.")
sys.exit()
else:
return the_file
def next_line(the_file):
"""Return next line from the trivia file, formatted."""
line = the_file.readline()
line = line.replace("/", "\n")
return line
def next_block(the_file):
"""Return the next block of data from the triva file."""
category = next_line(the_file)
question = next_line(the_file)
answers = []
for i in range(4):
answers.append(next_line(the_file))
correct = next_line(the_file)
if correct:
correct = correct[0]
explanation = next_line(the_file)
value = next_line(the_file)
return category, question, answers, correct, explanation, value
def welcome(title):
"""Welcome the player and get his or her name."""
print("\t\tWelcome to Trivia Challenge!\n")
print("\t\t", title, "\n")
def saving(player_name):
import pickle
f = open("trivia_scores.dat", "rb+")
highscores = pickle.load(f)
if player_name in highscores and score > highscores[player_name]:
highscores[player_name] = score
pickle.dump(highscores, f)
elif player_name not in highscores:
highscores[player_name] = score
pickle.dump(highscores, f)
print("The current high scores are as follows:")
print(highscores)
f.close()
def main():
trivia_file = open_file("trivia.txt", "r")
title = next_line(trivia_file)
welcome(title)
score = 0
#Get the first block
category, question, answers, correct, explanation, value = next_block(trivia_file)
while category:
#Ask a question
print(category)
print(question)
for i in range(4):
print("\t", i + 1, "-", answers[i])
#Get answer
answer = input("What is your answer?: ")
#Check answer
if answer == correct:
print("\nRight!", end=" ")
score += int(value)
else:
print("\nWrong!", end=" ")
print(explanation)
print("Score:", score, "\n\n")
#Get the next block
category, question, answers, correct, explanation, value = next_block(trivia_file)
trivia_file.close()
print("That was the last question!")
print("Your final score is", score)
return score
player_name = input("First, enter your name: ")
main()
saving(player_name)
input("\n\nPress the enter key to exit.")
The eponymous error occurs at this point:
def saving(player_name):
import pickle
f = open("trivia_scores.dat", "rb+")
highscores = pickle.load(f)
When the questions end, the program attempts to run the "saving" module, which (In theory) opens the trivia_scores.dat file, loads the highscores dictionary, checks to see if the player's name is in the dictionary, and if their current score is higher than the one in the file, it overwrites it.
But for some reason, when the program attempts to load the highscores dictionary, instead I get this error message.
EOFError: Ran out of input
I have never seen this error before. From some cursory googling, I got the impression that it has something to do with the program trying to read from an empty file. But that made no sense to me, since I specifically created a dat file using a different program to prevent that from happening: trivia_scores.dat is NOT an empty file. I even read from it with Python Shell to make sure.
What does this error mean, and why won't Python load the dat file?
Context: The book I'm reading from is Python for the Absolute Beginner, by Michael Dawson. This program and the challenge I'm trying to complete come from chapter 7. The program was running fine before I added the saving module.
Probably the original trivia_scores.dat file you wrote got corrupt (maybe you didn't call close() on it?). You should try creating a new file and adding a pre-populated dictionary to this file. Then try reading from this new file.

finding item in text file during 2nd read

In the beginning of my program, i opened a file with f = open("foods.txt", "r+"). Later I called this method i created
def findFood(food):
foodRegex = re.compile(r'(?P<food>\S+)\s+\-.*')
for line in f.readlines():
print line
duplicateFound = re.search(foodRegex, line)
if duplicateFound.group('food') == food:
return duplicateFound
else:
return False
However I run the method again. But my program doesn't work the way I want it to. Specifically
def build_meal_plan():
number_of_items = int(raw_input("How many items would you like to add to your meal plan? "))
count = 0
while number_of_items > 0:
print count
food = raw_input("Enter in food name: ")
print food
if findFood(food):
servings = int(raw_input("Number of servings: "))
else:
print "Food not found! Try again? (y/n): ",
choice = raw_input()
if choice == 'y' or choice == "yes":
number_of_items += 1
else:
return
However during the 2nd run of my findFood method I cannot locate an item i know exists within the .txt file. I am not sure why I cannot find the same item I found in the text file during the first run. My assumption is that you can only go through a txt file once.
Once you call f.readlines(), you are at the end of the file. To return to the start, so you can go through it again, call f.seek(0):
def findFood(food):
foodRegex = re.compile(r'(?P<food>\S+)\s+\-.*')
for line in f.readlines():
...
f.seek(0)
Alternatively, you can import the contents of the file to a list:
def import_file(filename):
with open(filename) as f:
content = [line.strip() for line in f]
return content
And use that instead of referring back to the file.
def findFood(food, data):
foodRegex = re.compile(r'(?P<food>\S+)\s+\-.*')
for line in data:
...
Then you don't need to worry about returning to the start.

Unpickle a Python dictionary via a loop?

I am very new to Python and what I am trying to achieve is to pickle a dictionary and then use some form of loop (apologies if I have the terminology incorrect!) to print all the scores in the file.
I am using Python 3.3.3 and here is my attempt, the user enters a name and a score which is first saved to a file and then I try to print it. However I am not able to print the scores.
import pickle
# store the scores in a pickled file
def save_scores(player, score):
f = open("high_score.dat", "ab")
d = {player:score}
pickle.dump(d, f)
f.close
# print all the scores from the file
def print_scores():
# this is the part that I can't get to work!
with open("high_score.dat", "r") as f:
try:
for player, score in pickle.load(f):
print("Player: ", player, " scored : ", score)
except EOFError:
pass
f.close
def main():
player_name = input("Enter a name: ")
player_score = input("Enter a score: ")
save_scores(player = player_name, score = player_score)
print_scores()
main()
input("\nPress the Enter key to exit")
I have Google'd and searched Stackoverflow for similar problems but I must be using the wrong terms as I haven't found a solution.
Thanks in advance.
pickle.load(f) will return a dictionary. If you iterate the dictionary, it yields keys, not key-values pairs.
To yield key-value paris, use items() method (use iteritems() method if you use Python 2.x):
for player, score in pickle.load(f).items():
print("Player: ", k, " scored : ", v)
To get multiple dictionaries out, you need to loop:
with open("high_score.dat", "r") as f:
try:
while True:
for player, score in pickle.load(f).items():
# print("Player: ", k, " scored : ", v) # k, v - typo
print("Player: ", player, " scored : ", score)
except EOFError:
pass
BTW, if you use with statement, you don't need to close the file yourself.
# f.close # This line is not necessary. BTW, the function call is missing `()`
pickle.load will return your dictionary ({player:score})
this code:
for player, score in pickle.load(f):
will try to unpack the returned value as a tuple.
Also, since you ignore the exception it will be hard to tell what went wrong.
I've done a few fixes to make your code work under Python 2 (no Python 3 is available, sorry). Several places were changed. Here it is with some notes:
#!/bin/python2
import pickle
# store the scores in a pickled file
def save_scores(player, score):
f = open("high_score.dat", "wb") # "wb" mode instead of "ab" since there is no obvious way to split pickled objects (surely you can make it, but it seems a bit hard subtask for such task)
d = {player:score}
pickle.dump(d, f)
f.close() # f.close is a method; to call it you should write f.close()
# print all the scores from the file
def print_scores():
# this is the part that I can't get to work!
with open("high_score.dat", "rb") as f: # "rb" mode instead of "r" since if you write in binary mode than you should read in binary mode
try:
scores = pickle.load(f)
for player, score in scores.iteritems(): # Iterate through dict like this in Python 2
print("Player: ", player, " scored : ", score) # player instead of k and score instead of v variables
except EOFError:
pass
# f.close -- 1. close is a method so use f.close(); 2. No need to close file as it is already closed after exiting `where` expression.
def main():
player_name = raw_input("Enter a name: ") # raw_input instead of input - Python 2 vs 3 specific
player_score = raw_input("Enter a score: ")
save_scores(player = player_name, score = player_score)
print_scores()
main()
raw_input("\nPress the Enter key to exit")

Categories

Resources