Python Forum
Pick random winners from .csv - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: Homework (https://python-forum.io/forum-9.html)
+--- Thread: Pick random winners from .csv (/thread-36862.html)



Pick random winners from .csv - DellXT - Apr-06-2022

Hi. I'm totally new to python. Just trying to find out how to pick few, but not the same (unique by ID) winners from the .csv file. Anyone could help?

This code picks only one. I guess I need to store those values in a list.

def generate():
    global filename, totalEntries, timestamp, winnerName, winnerID, winnerEmail
    filename = enterFile()

    now = datetime.datetime.now()
    timestamp = now.strftime("%B %d, %Y %I:%M:%S %p")

    with open(filename, newline="") as entriesCSV:
        entriesDict = csv.reader(entriesCSV,dialect="excel")

        totalEntries = len(list(entriesDict)) - 1 # ignore our header row

    winningNumber = random.randint(1,totalEntries)

    with open(filename, newline="") as entriesCSV:
        entriesDict = csv.DictReader(entriesCSV,dialect="excel")

        for row in entriesDict:
            if int(row["#"]) == winningNumber:
                winnerName = row["Name"]
                winnerID = row["ID"]
                winnerEmail = row["Email"]
                print(f"The winner is {winnerName}, ID {winnerID}, email {winnerEmail}")
And store picked values into one .docx file like this:

def createAuditSheet():
    doc = docx.Document()
    doc.add_paragraph("Giveaway: __________________________________________________________________________________________")
    doc.add_paragraph("______________________________________________________________________________________________________")
    doc.add_paragraph("Prize: _______________________________________________________________________________________________")
    doc.add_paragraph(f"The winner is {winnerName}, ID {winnerID}, email {winnerEmail}.")
    doc.add_paragraph(f"Drawn {timestamp} by user {currentUser} from {totalEntries} total entries found in file {filename}")
    for i in range(5):
        doc.add_paragraph("")
    doc.add_paragraph("Signature _________________________________________________________________ Date ___________________")
    doc.add_paragraph("Pick Up Date ___________________")
    doc.save("GiveawayDrawingResults.docx")



RE: Pick random winners from .csv - deanhystad - Apr-06-2022

Have you looked at the random library? There are functions other than randint that are a better fit for picking multiple items from a collection without any repeats.


RE: Pick random winners from .csv - DellXT - Apr-07-2022

What have I tried - edited the generation function to make it choose 5 winners (unfortunately, it didn't worked):

def generate():
    filename = enterFile()

    noOfWinners = 5
    winningNumbers = []
    while len(winningNumbers) < noOfWinners:
        luckyNumber = random.randint(1, totalEntries - 1)
        if luckyNumber not in winningNumbers:
            winningNumbers.append(luckyNumber)

    with open(filename, newline="") as entriesCSV:
        entriesDict = csv.DictReader(entriesCSV,dialect="excel")

        for number in winningNumbers:
            for row in entriesDict:
                if int(row["#"]) == number:
                    winnerName = row["Name"]
                    winnerID = row["ID"]
                    winnerEmail = row["Email"]
                    print(f"The winner is {winnerName}, ID {winnerID}, email {winnerEmail}")



RE: Pick random winners from .csv - Larz60+ - Apr-07-2022

Use a random number as the record (line) to select (as suggested by deanhystad), and only return that record (line).
  • from random import random
  • Run once: Get number of lines in input file: linecount = sum(1 for line in open(file))
  • Create random number between 1 and linecount: line_to_read = random.randint(1, linecount)
  • Read until record == line_to_read.
  • --- or ---
  • Read entire file record by record into a list
  • Use random number to select record
  • --- or ---
  • create list of file positions by reading file line by line and using f.tell
  • choose item from list using random number
  • Use f.seek to fetch selected record from the file.

Or something similar


RE: Pick random winners from .csv - deanhystad - Apr-07-2022

Why are you generating random numbers? You want to pick 5 winners. Open up the file and get all the users. Pick 5 at random. The only numbers you should care about are the user ID's since it sounds like the file may have more than 1 entry per user ID.


RE: Pick random winners from .csv - DellXT - Apr-08-2022

I made this:

def generate():
    global winningRows
    filename = enterFile()

    noOfWinners = 5
    winningNumbers = []
    while len(winningNumbers) < noOfWinners:
        luckyNumber = random.randint(1, totalEntries)
        if luckyNumber not in winningNumbers:
            winningNumbers.append(luckyNumber)

    with open(filename, newline='\n') as entriesCSV:
        entriesDict = csv.DictReader(entriesCSV,dialect="excel")
        allRows = [row for row in entriesDict]
        winningRows = [row for row in allRows if int(row["#"]) in winningNumbers]
        nonWinningRows = [row for row in allRows if int(row["#"]) not in winningNumbers]
        for row in winningRows:
            winnerName = row["Name"]
            winnerID = row["ID"]
            winnerEmail = row["Email"]
            print(f"The winner is {winnerName}, ID {winnerID}, email {winnerEmail}")

    with open(filename, "w", newline='\n') as entriesCSV:
        writer = csv.DictWriter(entriesCSV, fieldnames=["#", "Name", "ID", "Email"])
        writer.writeheader()
        writer.writerows(nonWinningRows)
But now I have a problem. Code deletes used rows (WinningRows) and if I use the file again, and random number is equal for the used and deleted number (#), it is not finding the new one. Just ignoring.


RE: Pick random winners from .csv - deanhystad - Apr-08-2022

Look at random.sample and think about how that could be used to select winners. Stop using randint,