简体   繁体   中英

Python declare winner using dictionary and loop

This is the output of the code I am trying to write. I have seen this done for C++, but not python with a dictionary. The key here is the dictionary is not optional. I need to use it to fulfill the assignment.

ID  Candidate           Votes Received      % of Total Vote
1   Johnson             5000                55.55
2   Miller              4000                44.44
Total 9000 
and the winner is Johnson!

I need to use a dictionary and a loop to create this. However, I am stuck on 3 points. 1.The percent- current code returns the percent before it has the whole total ex: first candidate always has 100%. 2. Declare a winner- code finds the max votes and returns the number value but I need it to return the name. 3. How to format the dictionary values so it lines up under the header. I don't think is possible, but it must be a requirement to use a dictionary for a reason. I am thinking I need to make a copy of the dictionary and format that? Here is what I have so far:

totalVotes=[]
dct = {}
i = 1
while(True):
    name = input('Please enter a name: ')
    if name == '':

        break
    votes = input('Please enter vote total for canidate: ')
    totalVotes.append(votes)
    totalVotesInt= map(int, totalVotes)
    total = sum(totalVotesInt)
    dct[i] = {name,votes,int(votes)/total*100}
    i += 1
header='{:>0}{:>10}{:>10}{:>20}'.format('ID','Name','Votes','% of Total Vote')
print(header)    
print("\n".join("{}\t{}".format(key, value) for key, value in dct.items()))
print('Total '+str(total))
print('The Winner of the Election is '+max(totalVotes))

Which returns:

    Please enter a name: Smith
    Please enter vote total for canidate: 100
    Please enter a name: Frieda
    Please enter vote total for canidate: 200
    Please enter a name: West
    Please enter vote total for canidate: 10
    Please enter a name: 
    ID      Name     Votes     % of Total Vote
    1   {'Smith', '100', 100.0}
    2   {'Frieda', 66.66666666666666, '200'}
    3   {3.225806451612903, '10', 'West'}
    Total 310
    The Winner of the Election is 200
  1. You add the number of each candidates votes at the same time you calculate the percent vote for each candidate. You need to find the total votes first, then divide each candidates votes by the total

  2. You are returning the max of a list of integers. Obviously you aren't going to get a string. You need some way to connect the number votes with the candidate.

  3. Don't bother. You can try to figure out how many tabs you need to get the whole thing lined up, but from experience, it is basically impossible. You could separate them with commas and open it in excel as a csv, or you could just make the user figure out what number goes with what.

The other answer uses data tables, so I will take another, more vanilla and cool approach to getting what you want.

class candidate():

  def __init__(self, name, votes):
    self.name = name
    self.votes = int(votes)

  def percentvotes(self, total):
    self.percent = self.votes/total

  def printself(self, i):
    print('{}\t{}\t\t{}\t\t{}'.format(i, self.name, self.votes, self.percent))

def getinput():
  inp = input('Please enter your candidates name and votes')
  return inp
candidates = []
inp = getinput()
s = 0
while inp != '':
  s+=1
  candidates.append(candidate(*inp.split(" ")))
  inp = getinput()

for c in candidates:
  c.percentvotes(s)

candidates.sort(key = lambda x:-x.percent)

print('ID\tname\t\tvotes\t\tpercentage')
for i, c in enumerate(candidates):
  c.printself(i+1)

I have added very little changes to your code to make it work:

I have mentioned the changes as comments in the code.

Edit: It's more efficient to use objects for each candidate if you require scaling in the future.

totalVotes=[]
dct = {}
i = 1
while(True):
    name = input('Please enter a name: ')
    if name == '':

        break
    votes = input('Please enter vote total for canidate: ')
    totalVotes.append(votes)
    totalVotesInt= map(int, totalVotes)
    total = sum(totalVotesInt)
    # I change it to a list so it's much easier to append to it later
    dct[i] = list((name,int(votes)))   
    i += 1

# I calculate the total percent of votes in the end and append to the candidate

maxVal = 0
for i in range(1, len(dct) + 1):
    if dct[i][1] > maxVal:
        maxInd = i
    dct[i].append(int((dct[i][len(dct[i]) - 1]) / total * 100))

header='{:>0}{:>10}{:>10}{:>20}'.format('ID','Name','Votes','% of Total Vote')
print(dct)
print(header)    
print("\n".join("{}\t{}".format(key, value) for key, value in dct.items()))
print('Total '+str(total))
print('The Winner of the Election is '+ dct[maxInd][0]))

I believe that this is the solution you are looking for. Just change the input statements in case you are using Python 2.x. Using Dataframe, the output will be exactly how you wanted.

import pandas as pd
import numpy as np
df = pd.DataFrame(columns=["Candidate", "Votes Received","Percentage of total votes"])
names=list()
votes=list()
while True:
    name = str(input("Enter Name of Candidate."))
    if name=='':
        break
    else:
        vote = int(input("Enter the number of votes obtained."))
        names.append(name)
        votes.append(vote)
s=sum(votes)
xx=(votes.index(max(votes)))
myArray = np.array(votes)
percent = myArray/s*100

for i in range(len(names)):
    df1 = pd.DataFrame(data=[[names[i],votes[i],percent[i]]],columns=["Candidate", "Votes Received","Percentage of total votes"])
    df = pd.concat([df,df1], axis=0)

df.index = range(len(df.index))
print (df)
print ("Total votes = ",s)
print ("The man who won is ",names[xx])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM