Python Forum
Pick random winners from .csv
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Pick random winners from .csv
#1
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")
Reply
#2
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.
Reply
#3
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}")
Reply
#4
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
Reply
#5
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.
Reply
#6
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.
Reply
#7
Look at random.sample and think about how that could be used to select winners. Stop using randint,
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020