Python: leaderboard - python

I have been asked to design a leader board,
This is what I tried
def leader():
file = open ("res.txt","r")
reader = csv.reader(file)
print (("{:20s}{:20s}{:20s}{:20s}".format("\nPlayer","Matches played","Won","Lost")))
won = 100
for r in reader:
won = won-1
if r[2] == str(won):
print (("{:20s}{:20s}{:20s}{:20s}".format(r[0],r[1],r[2],r[3])))
file.close()
My csv file looks like this
Leeroy,19,7,12
Jenkins,19,8,11
Tyler,19,0,19
Napoleon Wilson,19,7,12
Big Boss,19,7,12
Game Dude,19,5,14
Macho Man,19,3,16
Space Pirate,19,6,13
Billy Casper,19,7,12
Otacon,19,7,12
Big Brother,19,7,12
Ingsoc,19,5,14
Ripley,19,5,14
M'lady,19,4,15
Einstein100,19,8,11
Dennis,19,5,14
Esports,19,8,11
RNGesus,19,7,12
Kes,19,9,10
Magnitude,19,6,13
I wish for it to display the person with the most wins first, can you help?

Try slurping the file into a list:
all_rows = list(reader)
Then sort all the rows on the key of most wins:
sorted_rows = sorted(all_rows, key=(lambda row: row[2]), reverse=True)
You might want to stack several sorts, or define a more complex key, so that you can enforce ordering within equal numbers of wins (for example, 7 wins of 8 plays is better than 7 wins of 100 plays).

keys = ["Player","Matches played","Won","Lost"]
# read file
with open("res.txt") as f:
content = f.readlines()
# you may also want to remove whitespace characters like `\n` at the end of each line and
# split it by ',' then form a dictionary out of it
content = [dict(zip(keys,x.strip().split(','))) for x in content]
# sort the above list of dicts in decreasing orde.
final_result = sorted(content, key=lambda k: k['Won'], reverse=True)
print final_result# sorted By score
# first element is the one with highest Won value
print final_result[0] # highest Won

Related

Write map to a csv in python

I am not sure if the title of this is right. I know it is not a list and I am trying to take the results into a dictionary, but it is only adding the last value of my loop.
So I have pasted all my code but I have a question specifically on my candidates loop, where I am trying to get the percentages of votes per candidate. When I print the information it looks like this:
enter image description here
As you can see the 3rd session of the results is showing the candidates and next to them the percentage and the total votes. This results is what I am not sure what is (not a list not a dictionary)
I am trying to write this in my output csv, however after so many ways I always get to write only the last result which is O'Tooley.
I am new at this, so I am not sure first, why even if I save my percentage in a list after each loop, I am still saving only the percentage of O'Tooley. That's why I decided to print after each loop. That was my only way to make sure all the results look as in the picture.
import os
import csv
electiondatapath = os.path.join('../..','gt-atl-data-pt-03-2020-u-c', '03-Python', 'Homework', 'PyPoll', 'Resources', 'election_data.csv')
with open (electiondatapath) as csvelectionfile:
csvreader = csv.reader(csvelectionfile, delimiter=',')
# Read the header row first
csv_header = next(csvelectionfile)
#hold number of rows which will be the total votes
num_rows = 0
#total votes per candidate
totalvotesDic = {}
#list to zip and write to csv
results = []
for row in csvreader:
#total number of votes cast
num_rows += 1
# Check if candidate in the dictionary keys, if is not then add the candidate to the dictionary and count it as one, else sum 1 to the votes
if row[2] not in totalvotesDic.keys():
totalvotesDic[row[2]] = 1
else:
totalvotesDic[row[2]] += 1
print("Election Results")
print("-----------------------")
print(f"Total Votes: {(num_rows)}")
print("-----------------------")
#get the percentage of votes and print result next to candidate and total votes
for candidates in totalvotesDic.keys():
#totalvotesDic[candidates].append("{:.2%}".format(totalvotesDic[candidates] / num_rows))
candidates_info = candidates, "{:.2%}".format(totalvotesDic[candidates] / num_rows), "(", totalvotesDic[candidates], ")"
print(candidates, "{:.2%}".format(totalvotesDic[candidates] / num_rows), "(", totalvotesDic[candidates], ")")
#get the winner out of the candidates
winner = max(totalvotesDic, key=totalvotesDic.get)
print("-----------------------")
print(f"Winner: {(winner)}")
print("-----------------------")
#append to the list to zip
results.append("Election Results")
results.append(f"Total Votes: {(num_rows)}")
results.append(candidates_info)
results.append(f"Winner: {(winner)}")
# zip list together
cleaned_csv = zip(results)
# Set variable for output file
output_file = os.path.join("output_Pypoll.csv")
# Open the output file
with open(output_file, "w") as datafile:
writer = csv.writer(datafile)
# Write in zipped rows
writer.writerows(cleaned_csv)
In each iteration, you created a variable named candidates_info for just one candidate. You need to concatenate strings like this example:
candidates_info = ""
for candidates in totalvotesDic.keys():
candidates_info = '\n'.join([candidates_info, candidates + "{:.2%}".format(totalvotesDic[candidates] / num_rows) + "("+ str(totalvotesDic[candidates])+ ")"])
print(candidates_info)
# prints
# O'Tooley 0.00%(2)
# Someone 30.00%(..)
Also, you don't need keys(). Try this instead:
candidates_info = ""
for candidates, votes in totalvotesDic.items():
candidates_info = '\n'.join([candidates_info, str(candidates) + "{:.2%}".format(votes / num_rows) + "("+ str(votes)+ ")"])

Im not sure how i can make my program sort and read from an external file

I am creating a dice game in a nut shell and the scores get saved to an external file name 'scores'
Krystian: 5
Adam: 7
Unknown: 2
AWD: 18
Muaadh: 5
Yasir: 6
Zaim: 7
Ishfaq: 5
Tanzeel: 87
Hamzah: 3
Mohammed: 5
Robert: 6
Yasir: 5
Krystian: 61
Natalie: 72
and these are the usernames and their scores. I have seen some csv sort algorithms but the problem is that i am only a beginner and i don't have a clue on how they work so i can't really use them. What im really looking for is an explanation of how to sort them from highest score down to the lowest score and i want the program to print out the top 5 players.
with open('scores.txt', newline='') as f:
data = [{k: v for k, v in row.items()} for row in csv.DictReader(f, delimiter=':', fieldnames=['name', 'score'], quoting=csv.QUOTE_NONE)]
sorted_data = sorted(data, key = lambda i: i['score'], reverse=True)
for x in sorted_data:
print (x['name'] + ': ' + x['score'])
so far that is all i have managed to 'copy' from other posts but it still doesn't work properly. I think it's worth sharing that when u run the program it asks the user for their name, then it gets their score then it saves to the file and at the very end is where i ask the user if they would like to see top 5 players , so that is where i want my program to sort the external file and print out the top 5 players.
I do apologise as i have seen many posts like this but the only reason i post this myself is because i really don't understand any of them. Thanks for making it this far.
You have got it 80% of the way, you just need to isolate the top 5 scores, get rid of the leading white spaces, and convert the strings to integers. I would recommend using a dictionary instead of a csv file, but what you have is working. You also have duplicates in your csv, which using a dictionary would fix.
with open('scores.txt', newline='') as f:
# Stripping the leading spaces off of the numbers and names
data = [{k.strip(): v.strip() for k, v in row.items()} for row in csv.DictReader(f, delimiter=':', fieldnames=['name', 'score'], quoting=csv.QUOTE_NONE)]
# Making the string an integer
sorted_data = sorted(data, key = lambda i: int(i['score']), reverse=True)
# Isolating the top 5 results using indexes.
for x in sorted_data[:5]:
print (x['name'] + ': ' + x['score'])
I think one of your problems is using a dictionary, which is non-sequential and doesn't support sorts. You can instead make a list of every name, score pair in your file. Just put the score first, and then you can call sorted on this list:
highscores = []
with open('scores.txt') as file_object:
for line in file_object:
name, score = line.rstrip().split(':')
highscores.append ([int(score), name])
sorted_scores = sorted(highscores)
Then if you want to print out the scores:
for score, name in sorted_scores:
print (name + ': ' + str(score))

How to make a text file (name1:hobby1 name2:hobby2) into this (name1:hobby1, hobby2 name2:hobby1, hobby2)?

I'm new to programming and I need some help. I have a text file with lots of names and hobbies that looks something like this:
Jack:crafting
Peter:hiking
Wendy:gaming
Monica:tennis
Chris:origami
Sophie:sport
Monica:design
Some of the names and hobbies are repeated. I'm trying to make the program display something like this:
Jack: crafting, movies, yoga
Wendy: gaming, hiking, sport
This is my program so far, but the 4 lines from the end are incorrect.
def create_dictionary(file):
newlist = []
dict = {}
file = open("hobbies_database.txt", "r")
hobbies = file.readlines()
for rows in hobbies:
rows1 = rows.split(":")
k = rows1[0] # nimi
v = (rows1[1]).rstrip("\n") # hobi
dict = {k: v}
for k, v in dict.items():
if v in dict[k]:
In this case I would use defaultdict.
import sys
from collections import defaultdict
def create_dictionary(inputfile):
d = defaultdict(list)
for line in inputfile:
name, hobby = line.split(':', 1)
d[name].append(hobby.strip())
return d
with open(sys.argv[1]) as fp:
for name, hobbies in create_dictionary(fp).items():
print(name, ': ', sep='', end='')
print(*hobbies, sep=', ')
Your example give me this result:
Sophie: sport
Chris: origami
Peter: hiking
Jack: crafting
Wendy: gaming
Monica: tennis, design
you may try this one
data = map(lambda x:x.strip(), open('hobbies_database.txt'))
tmp = {}
for i in data:
k,v = i.strip().split(':')
if not tmp.get(k, []):
tmp[k] = []
tmp[k].append(v)
for k,v in tmp.iteritems():
print k, ':', ','.join(v)
output:
Monica : tennis,design
Jack : crafting
Wendy : gaming
Chris : origami
Sophie : sport
Peter : hiking
You could try something like this. I've deliberately rewritten this as I'm trying to show you how you would go about this in a more "Pythonic way". At least making use of the language a bit more.
For example, you can create arrays within dictionaries to represent the data more intuitively. It will then be easier to print the information out in the way you want.
def create_dictionary(file):
names = {} # create the dictionary to store your data
# using with statement ensures the file is closed properly
# even if there is an error thrown
with open("hobbies_database.txt", "r") as file:
# This reads the file one line at a time
# using readlines() loads the whole file into memory in one go
# This is far better for large data files that wont fit into memory
for row in file:
# strip() removes end of line characters and trailing white space
# split returns an array [] which can be unpacked direct to single variables
name, hobby = row.strip().split(":")
# this checks to see if 'name' has been seen before
# is there already an entry in the dictionary
if name not in names:
# if not, assign an empty array to the dictionary key 'name'
names[name] = []
# this adds the hobby seen in this line to the array
names[name].append(hobby)
# This iterates through all the keys in the dictionary
for name in names:
# using the string format function you can build up
# the output string and print it to the screen
# ",".join(array) will join all the elements of the array
# into a single string and place a comma between each
# set(array) creates a "list/array" of unique objects
# this means that if a hobby is added twice you will only see it once in the set
# names[name] is the list [] of hobby strings for that 'name'
print("{0}: {1}\n".format(name, ", ".join(set(names[name]))))
Hope this helps, and perhaps points you in the direction of a few more Python concepts. If you haven't been through the introductory tutorial yet... i'd definitely recommend it.

I need to parse some text and integers from a file

I'm having trouble with a problem I'm trying to do. My goal is to import a file that contains football teams names, and then the number of wins and losses, and then if a team's average is greater than .500, than I have to write that teams name, and average to a new file. And then I have to write the teams under .500 to a seperate file. so far I have my code so that it reads eachline of the file, but I can't figure out how to analyize each line of code. I'm really just looking for any advice I could get at this point, and it would be greatly appreciated.
scores = open("fbscores.txt",'r')
eachline = scores.readline()
while eachline != "":
print(eachline)
eachline = scores.readline()
scores.close()
Given an example line of the file like this:
Cowboys 4 1
Then some code might look like this:
line = scores.readline().split()
teamName = line[0]
wins = int(line[1])
losses = int(line[2])
if wins > losses:
print(teamName + "'s record is over .500!")
goodTeams.write(line)
goodTeams.write() #make a new line
else:
print(teamName + "'s record is <= .500.")
badTeams.write(line)
badTeams.write()
To find the average of a team with x wins and y losses, do:
"%0.3f" % (x/(x+y))
Gives:
>>> "%0.3f" % (4/(4+1))
'0.800'
>>>
You are most likely going to end up using the split method, which breaks a string apart into a list element each time it encounters a certain character. Read more here http://www.pythonforbeginners.com/dictionary/python-split.
You could use a high level library to do so, like pandas.
It has many of the functionnalities you want!
import pandas as pd
df = pd.read_csv('file.csv')
print(df)
It's really helpful if you post some lines from your input.
According to your description, I assuming each line in your input has the following layout:
[NAME] X Y
Where, NAME is the team name, X is the number of wins, Y, the number of loses.
You can simply split the line by any delimiter (which is 'space' in this example case),
eachline = eachline.split()
If there was a comma separator, then you do eachline = eachline.split(',') and so on, you get the idea.
Then eachline will store a list of the following structure ['NAME', X, Y]
Then you can access X and Y to average them using: eachline[0] and eachline[1] respectively.

How to sort a large number of lists to get a top 10 of the longest lists

So I have a text file with around 400,000 lists that mostly look like this.
100005 127545 202036 257630 362970 376927 429080
10001 27638 51569 88226 116422 126227 159947 162938 184977 188045
191044 246142 265214 290507 296858 300258 341525 348922 359832 365744
382502 390538 410857 433453 479170 489980 540746
10001 27638 51569 88226 116422 126227 159947 162938 184977 188045
191044 246142 265214 290507 300258 341525 348922 359832 365744 382502
So far I have a for loop that goes line by line and turns the current line into a temp array list.
How would I create a top ten list that has the list with the most elements of the whole file.
This is the code I have now.
file = open('node.txt', 'r')
adj = {}
top_ten = []
at_least_3 = 0
for line in file:
data = line.split()
adj[data[0]] = data[1:]
And this is what one of the list look like
['99995', '110038', '330533', '333808', '344852', '376948', '470766', '499315']
# collect the lines
lines = []
with open("so.txt") as f:
for line in f:
# split each line into a list
lines.append(line.split())
# sort the lines by length, descending
lines = sorted(lines, key=lambda x: -len(x))
# print the first 10 lines
print(lines[:10])
Why not use collections to display the top 10? i.e.:
import re
import collections
file = open('numbers.txt', 'r')
content = file.read()
numbers = re.findall(r"\d+", content)
counter = collections.Counter(numbers)
print(counter.most_common(10))
Ideone Demo
When wanting to count and then find the one(s) with the highest counts, collections.Counter comes to mind:
from collections import Counter
lists = Counter()
with open('node.txt', 'r') as file:
for line in file:
values = line.split()
lists[tuple(values)] = len(values)
print('Length Data')
print('====== ====')
for values, length in lists.most_common(10):
print('{:2d} {}'.format(length, list(values)))
Output (using sample file data):
Length Data
====== ====
10 ['191044', '246142', '265214', '290507', '300258', '341525', '348922', '359832', '365744', '382502']
10 ['191044', '246142', '265214', '290507', '296858', '300258', '341525', '348922', '359832', '365744']
10 ['10001', '27638', '51569', '88226', '116422', '126227', '159947', '162938', '184977', '188045']
7 ['382502', '390538', '410857', '433453', '479170', '489980', '540746']
7 ['100005', '127545', '202036', '257630', '362970', '376927', '429080']
Use a for loop and max() maybe? You say you've got a for loop that's placing the values into a temp array. From that you could use "max()" to pick out the largest value and put that into a list.
As an open for loop, something like appending max() to a new list:
newlist = []
for x in data:
largest = max(x)
newlist.append(largest)
Or as a list comprehension:
newlist = [max(x) for x in data]
Then from there you have to do the same process on the new list(s) until you get to the desired top 10 scenario.
EDIT: I've just realised that i've misread your question. You want to get the lists with the most elements, not the highest values. Ok.
len() is a good one for this.
for x in data:
if len(templist) > x:
newlist.append(templist)
That would give you the current highest and from there you could create a top 10 list of lengths or of the temp lists themselves, or both.
If your data is really as shown with each number the same length, then I would make a dictionary with key = line, value = length, get the top value / key pairs in the dictionary and voila. Sounds easy enough.

Categories