I am creating a leaderboard creating system, where it checks if the Name is already in the Database, if not it adds it, and if it is it replaces the name and score.
import csv
winner =["Player", 100]
def leaderboardsave(winner):
fileCSV = open('scores.csv')
dataCSV = csv.reader(fileCSV)
playersScores = list(dataCSV)
winnerName = winner[0]
winner_index = playersScores.find(winnerName)
if winner_index > -1:
playersScores[winner_index] = winner
else:
playersScores.append(winner)
leaderboardsave(winner)
The CSV is saved like this:
Player, 20
Player2, 40
Player3, 30
Player4, 60
whenever I run
winner_index = playersScores.find(winnerName)
it returns "'list' object has no attribute 'find'"
Any other ways to find where the item is in the list? When i tried using .index, it wouldnt find it, i assume as it is looking for a list, not a single string?
You are getting that error because playerScores is a list object and a list object doesn't have a find function.
You can traverse a list to find a value by looping:
winner_index = [index for index, value in enumerate(playerScores) if value == winnerName]
Related
In the file values there are a bunch of lists and I want to assign gun_type to a value depending on what my current_gun_name is plus the string _Iron.
How do I do this? This is my current code but it doesnt work
current_gun_name = string_assigned_above
iron = win32api.GetAsyncKeyState(0x67)
if iron < KeyMin and win32api.GetAsyncKeyState(0x11) < 0:
gun_type = values.(current_gun_name + "_Iron")
So, on the last line there I am trying to pull a list from another file called values. But the list that I am trying to pull depends on the current_gun_name string. For example:
current_string = "test"
list_from_values = values.(current_gun_name + "ing")
print(list_from_values)
In this code it should find a list in the file called values. The list it will find and print will be called "testing" as I am asking it to use the variable plus "ing" Except this doesnt work
Hello I a developing a text based game and I'm struggling with the drop command ; the way it works is you write "D name of the item" then it checks if the item is actually in the inventory and if it is, it puts it in a variable, deletes it from the inventory and I want it to append to the content indice of a room (a dictionary) and that dictionary is in a list, and I can't append to it.
this is the code(some of it):
room = []
room.append({'number': 1, 'content': ""})
roomnumber = 1
inv = ["sword"]
command = input(": ")
first_letter = command(0)
if first_letter == "D":
item = command.split(" ", 2)
item.remove("D")
for i in range(0, len(inv):
inv.pop(i)
#this doesn't work
` room[roomnumber]['content'].append(item[0])`
item.pop(0)
After I have entered: "D sword", it gives me this error:
Traceback (most recent call last):
File "/Users/antony/PycharmProjects/TextBased/Main.py", line 54, in <module>
room[roomnumber]['content'].append(item[0])
AttributeError: 'str' object has no attribute 'append'
I don't get it, please help !
Do you want a room to be able to contain more than one thing? If so, make your content field a list rather than a string:
room.append({'number': 1, 'content': []})
Now you can append any number of things to the content.
room = []
room.append({'number': 1, 'content': ""})
## room = [{'number': 1, 'content': ""}]
roomnumber = 1
## you should actually change this to 0. Otherwise you will get an "index out
## of range" error (see comment below)
inv = ["sword"]
command = input(": ")
first_letter = command(0)
if first_letter == "D":
item = command.split(" ", 2)
## why are you adding a max split here??
item.remove("D")
for i in range(0, len(inv)):
## equals for i in range(0, 5):, so iterates 0,1,2,3,4
## you forgot to add a closing bracket for the range
inv.pop(i)
## what are you trying to do here? This looks strange to me, given that after each
## pop, the value of your inv will be shortened..?
#this doesn't work
room[roomnumber]['content'].append(item[0])
## this does not work because your room list only contains one element, a
## dictionary, at index position 0. Probably THIS is your biggest issue here.
## Second, you're trying to change the value of 'content'. To change the value of a
## dictionarie's key, you need to use "=", and not ".append", as ".append" is used
## to append an element at the end of a list, to a list, and not to a dictionary.
## So, use room[roomnumber]['content'] = item[0]
item.pop(0)
From what I understood, you want to add a content, in function of the roomnumber, to the content value of the dictionary of the corresponding room number. In this case, your whole syntax is wrong, and you must rather use:
room = []
room.append({1:""})
## and then, after the rest of the code:
room[roomnumber-1][roomnumber] = item[0]
or, even simpler, given that the simultaneous use of lists and dictionaries is actually obsolete here
## initiate one dictionary, containing all the rooms in key = roomnumber
## value = content pairs
rooms = {}
## the syntax to add a new room number with a new content into the dictionary
## would then simply be: rooms[number] = content, e.g.:
rooms[1] = ""
## to then set the value of the content for a given roomnumber, you simply use
rooms[roomnumber] = item[0]
I recommend you to learn about the basic differences in between lists and dictionaries in python, you seem to lack some basic understanding of how elements of lists and dictionaries are accessed / modified (no offense of course)
ok thanks a lot guys :), I just wanted to say that the reason that some things are a bit weird is because that is only about 20 % of the code ( there are more rooms for example witch is why I needed to use dictionaries in a list) and my room number does start with 0 in my actual code :), the pop is to remove the item from the inventory (because this is the drop command) and I remove it from the item variable just to be safe that it doesn't cause any unwanted bugs. and otherwise, yes the content WAS supposed to be a list, I forgot, thanks for pointing it out and the for loop is actually closed it ( I was just in a bit of a rush when I wrote this ). Anyway, thanks everyone :)
I am writing a program that keeps tab of the score of a card game and by the completion of the game generates a table with names of players, points and total profit/loss. I need some advice on how to execute one crucial aspect of scoring keeping for this project and hence I'll start by giving you the main lines of code of the project:
# takes player information//
player_number = int(input('number of players:'))
cards_per_player = int(input('cards per player:'))
# takes player data and generates dictionary
player_dict = {}
for x in range(1,player_number+1):
player_dict["player{0}".format(x)] = input('name of player:')
print (player_dict)
# takes the dictionary values and creates a list
players_keys = list(player_dict.values())
# function that takes an input for the 'hands' won for each round for each player in the game...maximum hands for each player are 3 and minimum are 0.
def round():
counter_for_round = []
for i in range(0,(len(players_keys))):
score_per_player = int((input(str(players_keys[i])+':')))
counter_for_round.append(score_per_player)`
The counter_for_round variable stores data on each player's count of hands for any particular round. For example, if the total number of players were three, the list would look like: [1,1,0] or [3,0,0] or [2,1,0] and etc etc. Now, what I want it is to generate variables with empty lists for each item within the list 'players_keys'. So, for example, if players_keys = [a,b,c], I want to generate three variables, a b and c, which are empty lists in order for me to store the total scores within them for each player.
How do I go about this? Also, I know that this method can be quite detrimental and hence I am curious as to whether you can think of a simpler way to execute this?
Since you dont know how many players there are, you shouldnt try to create "new variables" for each player, but use a dictionary instead like you already did with player_dict.
So your result would be score = {key: list() for key in players_keys}, which is a dictionary with every player name as a key and an empty list as a value.
Also i'm not sure why you even need player_dict since the new score variable would include all important information. So maybe merging input of player names and list creation would be better.
# takes player data and generates dictionary
player_dict = dict()
for x in range(0, player_number):
player_name = input('name of player:')
player_dict[player_name] = list()
# takes the dictionary values and creates a list
players_keys = list(player_dict.keys())
In a section of a game I am creating a user enters a username. The username and user's score are saved in an object which is pickled to an external file which has the other pickled score objects in it.
I then have a button on the UI that if clicked should display the Highest scores of all players in descending order.
I load in the file into a list with the code I found here .
Highscores = []
Highscores = pickle.load(open("Highscores.txt", "rb"))
I then use a bubble sort to sort the list of objects shown below.
def bubbleSort():
swapOccured = True
while swapOccured == True:
swapOccured = False
for i in Highscores:
if Highscores[i].score > Highscores[i + 1].score:
hold = Highscores[i + 1]
Highscore[i + 1] = Highscores[i]
Highscores[i] = Highscores[i + 1]
swapOccured = True
The error that is getting returned is
for index in Highscores:
TypeError: iteration over non-sequence
I have looked at other questions like this for example here but the error was that the program was looping through an object not looping through a list of objects. I'm pretty sure it's not the same error as the example, I think it could be with loading in a list of objects with pickle but I'm stuck.
Any help would be greatly appreciated.
Just like pickle.dump dumps a single object to the file, pickle.load loads a single object from the file. If you want a list, you will need to load them all:
with open("Highscores.txt", "rb") as score_file:
Highscores = []
while True:
try:
Highscores.append(pickle.load(score_file))
except EOFError:
break
Python is my first language, and I am very new to it, so the answer may be very clear, but after many hours looking and experimenting, I am not sure what is causing the problem.
An overview of the module:
The DicePool module is meant to manage collections of "dice", stored as dictionary items. Each dictionary key (herein poolKey) has a list containing information about one "type" of dice, most importantly, a tuple describing its faces and an integer representing the quantity of "dice" type 'x' in the "pool."
My specific question regards the Transfer method, which used to be two methods (send and receive, basically), but which I thought I could combine into one method. When the test code at the bottom runs, I'd like it to leave dp.dictPool[poolKey][1] == 0 and dp2.dictPool[poolKey][1] == 2. But in every attempt I've made, the values come out the same. Sorry I can't categorize this question better . . . I don't really know what the problem is.
Anyway, one half of the Transfer method is supposed to run for the "sender" instance, and one half is supposed to run for the "receiver" instance.
import random
class DicePool(object):
def __init__(self):
self.dictPool = {}
def AddDice(self, poolKey, faces = 6, quant = 1, color = "white"):
'''faces must be int or items 'a,b,c'; count must be int or def to 1'''
try: #if count is not an integer, it defaults to 1
quant = int(quant)
except:
print("Quant is not an integer, defaulting to 1")
quant = 1
try: #if faces is can be int, a list is built of numbers 1 to faces
faces = int(faces)
if faces < 2: #a 1 or 0-sided die breaks the program
faces = 2
tempList = []
for i in range(1, faces+1):
tempList.append(i)
faces = tempList
except: #if faces is not an integer, it is split into list items by ","
faces = faces.split(",")
if poolKey in self.dictPool.keys(): #if the key already exists in pool
self.dictPool[poolKey][1] += quant #add to the quantity,
else: #if the key does not already exist, set all attributes
self.dictPool[poolKey] = [faces, quant, color]
def Transfer(self, poolKey, targetPool, sendQuant, senderPool = None):
'''targetPool must be DicePool instance'''
if targetPool:
self.dictPool[poolKey][1] -= sendQuant
targetPool.Transfer(poolKey, None, sendQuant, self)
else:
try:
self.dictPool[poolKey][1] -= sendQuant
except:
self.dictPool[poolKey] = senderPool.dictPool[poolKey]
self.dictPool[poolKey][1] = sendQuant
dp = DicePool()
dp2 = DicePool()
dp.AddDice("d6")
dp.AddDice("d6")
dp.Transfer("d6",dp2,2)
print(dp.dictPool,dp2.dictPool)
The problem is in this line:
self.dictPool[poolKey] = senderPool.dictPool[poolKey]
The values in your dictPools are lists. Here, you set one object's dictPool value to the same list as in the other one. Not a copy of the list, but the same list. So later if you add or subtract from that list, it will affect the other as well, because they are sharing one list object.
Try doing self.dictPool[poolKey] = senderPool.dictPool[poolKey][:]. The [:] grabs the contents of the list rather than the list object iself.
In both parts of the if/else in Transfer you're subtracting the quantity. Don't you want to subtract it in one case but add it in the other?
Is else: try: self.dictPool[poolKey][1] -= sendQuant supposed to be += sendQuant instead?
Might be a semantic issue, not a Python syntax issue.
Here is a version of the Transfer() method that seems to work as intended (more or less), although it's very clumsy looking:
def Transfer(self, poolKey, targetPool, sendQuant, senderPool = None):
'''targetPool must be DicePool instance'''
if isinstance(targetPool, DicePool):
#valid target, so subtract dice here, then call Transfer on target
temp = self.dictPool[poolKey][1:2][0] - sendQuant
print("sent",sendQuant,"leaving",temp)
targetPool.Transfer(poolKey, "Receiver", sendQuant, self)
elif targetPool == "Receiver":
#this executes if a DicePool is named as the targetPool of Transfer
if poolKey in self.dictPool.keys():
self.dictPool[poolKey][1:2][0] += sendQuant
else:
self.dictPool[poolKey] = senderPool.dictPool[poolKey]
self.dictPool[poolKey][1:2] = [sendQuant]
print("now have",self.dictPool[poolKey][1:2][0])
pass
else:
print("Not a valid targetPool, apparently")