1

I am attempting to create a program, where the user can input multiple lottery ticket numbers, and it will compare these numbers to a set of winning numbers. I know I can make it work by using several if statements, but I'm thinking there has to be a way to do this in a loop. I've tried a few loops that used "for key in ___", but I kept receiving errors.

amount = int(input('How many sets of numbers do you have?'))
tickets = {}
ticketMatch = {}
winingNumbers = {
    '1': '1',
    '2': '2',
    '3': '3',
    '4': '4',
    '5': '5',
    '6': '6',
}

for i in range (0, amount, 1):
    tickets[i] = {
        '1': input('Input #1 '),
        '2': input('Input #2 '),
        '3': input('Input #3 '),
        '4': input('Input #4 '),
        '5': input('Input #5 '),
        '6': input('Input Powerball '),
    }


for i in range (0, len(tickets), 1):
    ticketMatch[i] = 0
    if tickets[i]['1'] in winingNumbers.values():
        ticketMatch[i] += 1
    if tickets[i]['2'] in winingNumbers.values():
        ticketMatch[i] += 1

Any tips or hints would be greatly appreciated. Thanks!

deadshot
  • 8,881
  • 4
  • 20
  • 39
Kyle
  • 13
  • 4
  • 3
    Welcome to SO! I'm not sure it makes much sense to use dicts like this. For one, if you're just calling `values()` on them, that's an O(n) lookup operation--the idea is to look up using a key to get a value. Also, your dicts are just 0..n sequential, so you may as well use lists here. I recommend zooming out a bit to describe the sort of output you're supposed to get given a set of input (and explain why) and let the design be less imposed. This avoids an [xy problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) scenario. Thanks. – ggorlen May 29 '20 at 05:03
  • @ggorlen makes a good point; to help you see what is meant by that, your code raises questions like: why use a `dict` instead of a `list` (both for `tickets` and for `winningNumbers`)? why do your dicts have `str` keys? But also: what do you need `ticketMatch` for once it's completely constructed? What's the goal of your code? – Grismar May 29 '20 at 05:18

3 Answers3

0
amount = int(input('How many sets of numbers do you have?'))
winingNumbers = {1, 2, 3, 4, 5, 6}
tickets = [set() for _ in range(amount)]
ticketMatch = []


for i in range(amount):
    for j in range(6):
        if j == 5:
            tickets[i].add(int(input("Input Powerball ")))
        else:
            tickets[i].add(int(input("Input #" + str(j + 1) + " ")))

for i in range(amount):
    ticketMatch.append(len(tickets[i] & winingNumbers))
0

To iterate through any dictionary is pretty straightforward. Say we have the following dictionary:

d = {
    "a": 1,
    "z": 26
}

and we wanted to print out the keys with their values.

for key in d: # note, key represents "a" and "z"
    print(key, d[key])

However, for the purposes of what you're trying to accomplish, dictionaries might not be necessary at all, like @ggorlen commented.

A quick rendition I came up with to do the same thing

query = "enter a lottery number or 'quit' to quit: "
entries = input(query)
numbers = []
while entries != "quit":
    numbers.append(entries)
    entries = input(query)

winning_numbers = "123456"

for i in range(len(numbers)):
    if numbers[i] == winning_numbers:
        print(f"ticket {i} is a winner!")

I'm not sure why you're checking every tickets' number 1 and 2 against the total winning numbers because that's not how normal lotteries work, which is why my version looks a bit different, but of course you could make that change easily if it was what you wanted.

notacorn
  • 3,526
  • 4
  • 30
  • 60
0
  • Dictionaries make only sense if you have a key and store a value by it. Accessing the value of a key and checking if a key is part of a dictionary is fast (O(1)) - iterating all values of a dict is as slow as a list - but creating the dictionary is slower then creating a list and occupies more of your computers memory.
  • Using set operations avoid using if's cascades - for an example see further below.

Faster input in a loop can be done using split() and list decomposing *a,b=[1,2,3,4]:

for _ in range(int(input("How many tickets do you want to enter? "))):
    *nums, power = map(int, 
         input( ("Input space seperated numbers of your ticket,"
                 " last one is Powerball: ") ).strip().split())
    print(nums, power)    

Output:

How many tickets do you want to enter? 3
Input space seperated numbers of your ticket, last one is Powerball: 1 2 3 4 99
    [1, 2, 3, 4] 99
Input space seperated numbers of your ticket, last one is Powerball: 2 3 4 7 199
    [2, 3, 4, 7] 199
Input space seperated numbers of your ticket, last one is Powerball: 4 2 4 5 6
    [4, 2, 4, 5] 6

(Although some more checking might be appropirate for Users that do not enter numebrs at all or too few/out of range ones: Asking the user for input until they give a valid response )


For lotto comparisons a list of "tickets" with a set() of numbers each can be fastly checked correct numbers using set-operations.

Checking the list of tickets will be O(n) (with n == amount of tickets) - checking if numbers match your winning numbers is fast: O(1) and avoids if ..:.

You could do this like so (fully random example):

import random 

def random_nums():
    """Returns a tuple of a frozenset of 5 numbers in the range [1..69]
    and one number in the range of [1..26] (aka: USA Powerball Lottery)"""
    return ( frozenset(random.sample(range(1,70), 5)), random.choice(range(1,27)) )

# draw the win-numbers
winning_nums = set(random.sample(range(1,70), 5))
powerball = random.choice(range(1,27))
# print them
print("Winner: ", *winning_nums, "   Powerball: ", powerball)


# generate random tickets
tickets = [ random_nums() for _ in range(10) ]

# check if ticket got something in common with winner numbers
for (nums, power) in tickets: 
    # fast set operations
    intersect = sorted(nums.intersection(winning_nums))
    wrong = sorted(nums.difference(winning_nums))
    p = 'correct' if power == powerball else 'wrong'
    n = "'nothing'"
    # some output
    print( ( f"You got {intersect or n} correct and guessed "
             f"{wrong or n} wrong. Powerball: {p}.") )

Output:

Winner:  14 49 26 27 60    Powerball:  6

You got [49] correct and guessed [21, 41, 59, 66] wrong. Powerball: wrong.
You got [60] correct and guessed [17, 19, 63, 68] wrong. Powerball: wrong.
You got 'nothing' correct and guessed [10, 21, 51, 67, 69] wrong. Powerball: wrong.
You got 'nothing' correct and guessed [18, 30, 40, 45, 52] wrong. Powerball: wrong.
You got [26, 27] correct and guessed [11, 37, 58] wrong. Powerball: wrong.
You got 'nothing' correct and guessed [28, 33, 38, 59, 65] wrong. Powerball: wrong.
You got 'nothing' correct and guessed [11, 18, 35, 61, 64] wrong. Powerball: wrong.
You got 'nothing' correct and guessed [2, 3, 47, 54, 63] wrong. Powerball: wrong.
You got [14] correct and guessed [23, 25, 58, 66] wrong. Powerball: wrong.
You got [27] correct and guessed [47, 52, 56, 58] wrong. Powerball: correct.

See:

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69