3
\$\begingroup\$

I wrote a rather inapt lotto simulator in Python, showing how long it would take to win the jackpot. I ran a similar application implemented in C, and it is so much faster. I know you can't compare the two, but I wonder anyway if there is room for performance improvement in my code. By the way, I converted my code using Cython into C, with no speed gain.

import random, locale
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
r_list = []
super_number = 0
my_super_number = 5
my_list = [[3, 4, 45, 7, 23, 33], [1, 2, 3, 4, 5, 6], [13, 43, 33, 15, 17, 18], [11, 14, 2, 17, 33, 13],
 [1, 2, 14, 15, 25, 26], [23, 26, 37, 40, 43, 44]] # each list within corresponds to 1 games per drawing
match_list = []
iteration = 0
number_matches = 0
def fill_random_list():
 for i in range(6):
 # print (random.randint(1,49))
 r_list.append(random.randint(1, 49))
def return_matches(lista, listb):
 # print set(lista).intersection(listb)
 return set(lista).intersection(listb)
def return_number_matches(l_matches):
 if l_matches:
 return len(l_matches)
def print_communicate(v_iteration, v_number_matches, v_guess, v_r_list, v_match_list, v_super_number,
 v_my_super_number):
 print (
 'Drawing No.: ' + locale.format("%d", v_iteration, grouping=True))
 print ('My guess: ' + str(sorted(v_guess)) + ', Super Number: ' + str(v_my_super_number))
 print ('Result :' + str(sorted(v_r_list)) + ', Super Number: ' + str(v_super_number))
 print ('My hits: ' + str(sorted(v_match_list)) + ', Amount of hits: ' + str(v_number_matches))
 print ('Time to win: ' + str(calculate_time_to_win(v_iteration)) + ' Years')
 print ('---------')
def calculate_time_to_win(v_drawings):
 return (v_drawings/2)/365 # calculate years assuming participation in 2 lotteries a week
def draw_lottery(v_hits, v_with_super_number): #v_hits: number of hits until termination, v_with_super_number: include super number 'yes' or 'no'
 global iteration, number_matches, r_list, match_list, my_list, super_number, my_super_number
 jackpot = False
 while not jackpot:
 fill_random_list() # draw lottery results
 super_number = random.randint(1, 9) # draw super number
 for guess in my_list:
 match_list = return_matches(r_list, guess)
 number_matches = return_number_matches(match_list)
 if number_matches == v_hits:
 if v_with_super_number == 'yes':
 if my_super_number == super_number:
 print_communicate(iteration, number_matches, guess, r_list, match_list, super_number,
 my_super_number)
 jackpot = True
 if v_with_super_number == 'no':
 if my_super_number != super_number:
 print_communicate(iteration, number_matches, guess, r_list, match_list, super_number,
 my_super_number)
 jackpot = True
 match_list = []
 number_matches = 0
 if jackpot:
 break
 else:
 iteration += 1
 print 'Drawing No.: {0}'.format(iteration) + ' Years: {0}\r'.format(calculate_time_to_win(iteration)),
 r_list = []
 match_list = []
 number_matches = 0
def iterate(number): 
 for i in enumerate(range(number), 1):
 print('Round: ' + str(i[0]))
 draw_lottery(6, 'no') 
def main():
 iterate(1)
 print 'END!'
if __name__ == "__main__":
 main()
toolic
14.4k5 gold badges29 silver badges201 bronze badges
asked Oct 20, 2017 at 12:35
\$\endgroup\$
2
  • 1
    \$\begingroup\$ randint can generate many numbers at once. No need to call it many times. \$\endgroup\$ Commented Oct 21, 2017 at 20:43
  • 1
    \$\begingroup\$ In fact fill_random_list is already implemented in random module, it's called random.sample(). \$\endgroup\$ Commented Oct 22, 2017 at 15:09

1 Answer 1

2
\$\begingroup\$

Documentation

The PEP 8 style guide recommends adding docstrings for functions.

You should also add a docstring to the top of the code to summarize its purpose. For example:

"""
Lotto simulator, showing how long it would take to win the jackpot.
"""

Comments

Remove commented-out code to reduce clutter:

# print (random.randint(1,49))
# print set(lista).intersection(listb)

Simpler

The code would be simpler without this function:

def return_number_matches(l_matches):

It is only called once, and it really just executes len on its input.

Since the i variable is not used in the following loop:

for i in range(6):

the _ placeholder can be used:

for _ in range(6):

Portability

I realize this question was posted many years ago when Python version 2.x was prevalent, but now that it is deprecated, consider porting to 3.x.

For example, change:

print 'END!'

to:

print('END!')

This line:

print('Round: ' + str(i[0]))

is simpler with an f-string:

print(f'Round: {i[0]}')

If you want to control the precision of the output in the draw_lottery function:

print(f'Drawing No.: {iteration} Years: {calculate_time_to_win(iteration):.4f}')

Tools

You could run code development tools to automatically find some style issues with your code.

ruff shows:

E401 [*] Multiple imports on one line
 |
 | import random, locale
 | ^^^^^^^^^^^^^^^^^^^^^ E401
 | 
 | locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
 |
 = help: Split imports
answered Apr 14 at 10:29
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.