mrnovice - 1 year ago 57
Python Question

# Python debugging simple script

So as part of a script I'm writing to play tic tac toe, I have a 'win checker' which takes as its input:

1. a list of numbers which denote positions

2. who started the game

It's not really important for the problem I'm having, but I thought some background might help. Here is the code:

``````import matplotlib.pyplot as plt
import math
import numpy as np
import random
import pdb
def win_checker(position_list, turn2):
win_list1 = []
win_list2 = []
for bud in xrange(len(position_list)):
if bud % 2 == 0:
win_list1.append(position_list[bud])
print win_list1
if 1 and 2 and 3 in win_list1:
return True
if 4 and 5 and 6 in win_list1:
return True
if 7 and 8 and 9 in win_list1:
return True
if 1 and 4 and 7 in win_list1:
return True
if 2 and 5 and 8 in win_list1:
return True
if 3 and 6 and 9 in win_list1:
return True
if 1 and 5 and 9 in win_list1:
return True
if 3 and 5 and 7 in win_list1:
return True
elif bud % 1 == 0:
win_list2.append(position_list[bud])
print win_list2

if 1 and 2 and 3 in win_list2:
return True
if 4 and 5 and 6 in win_list2:
return True
if 7 and 8 and 9 in win_list2:
return True
if 1 and 4 and 7 in win_list2:
return True
if 2 and 5 and 8 in win_list2:
return True
if 3 and 6 and 9 in win_list2:
return True
if 1 and 5 and 9 in win_list2:
return True
if 3 and 5 and 7 in win_list2:
return True
else:
return False
``````

Then when I try the script for a certain position:

``````win_checker([5,1,3,2], 1)
[5]
[1]
[5, 3]
Out[57]: True
``````

I don't understand why the output is True, if someone could explain what I'm missing that would be very helpful to me

Detail of the problem:

The and operator works on boolean values only. It does not distribute over the in operator (remember the distributive law of multiplication over addition?). Your expression

``````1 and 2 and 3 in win_list1
``````

becomes

``````bool(1) and bool(2) and bool (3 in win_list1)
``````

bool(n) is False for n=0, True for everything else.

Immediate fix:

Alex Hall already gave you that

Better fix (perhaps):

Renumber your array of choices to be a magic square:

``````6 7 2
1 5 9
8 3 4
``````

Now, all you have to do is check whether you have a sum of 15 for any combination of three chosen positions. You can generate all of those with

``````itertools.combinations(win_list1, 3)
``````

This would reduce your checking from 18 lines to 1 (or 2-4, if you prefer that readability).

Extra issue:

Your logic on bud is a little weird. I do understand the odd/even checking on the turn number:

``````if bud % 2 == 0:
``````

However, the second one,

``````elif bud % 1 == 0:
``````

is True for any integer. The percent sign is the modulus operator: divide by the mod and keep the remainder. In short, the second one is always true. Just make it an else.

Another ...

Why not make win_list a 2-D list? Use win_list[0] and win_list[1], so you can fold their code together. You can simply have

``````player = bud % 2
win_list[player].append(position_list[bud])
if any(sum(itertools.combinations(win_list[player], 3)) == 15):
...
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download