[Tutor] misunderstanding "any"

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[Tutor] misunderstanding "any"

col speed
Hello again
Hope you are all well.

I'm trying to make a "match 3" game, where you have a square grid and
have to put 3 matching shapes in a row.
I need a function that tells me if the game is playable, ie. it is
possible to match 3 shapes by only swapping 2 adjacent shapes.
I have looked at the co-ordinates and got a list of the "offset
co-ordinates" needed for the above.

I have a list of coordinates and a list of "lemons" and I want to see
if *any* lemon coordinate is in the list of coordinates.
I tried this:
if any(((x+1, y+1), (x-1, y+2),(x-2, y+1),(x-1, y-1 ))) in fruit_type:
                    return True

Thinking that if  *any* of the tuples is in fruit_type(a list of
tuples), then it should return True.
However, it always equates to False.
If I iterate through the tuples and see if any are in fruit_type, it
returns True (when it should).
I have tried many print statements to make sure what is happening, and
also to make sure that I am comparing type<tuples>.

I just wondered what it is that I'm misunderstanding, or what I've done wrong.

Here is the whole programme for completeness:



#!usr/bin/env python

import random

class Gem(object):
    def __init__(self, x, y, fruit):
        self.x = x
        self.y = y
        self.fruit = fruit

gems = []
x, y = 0, 0
fruits = ["lemon", "banana", "apple", "pineapple", "mango"]

for gem in range(81):
    gems.append(Gem(x, y, random.choice(fruits)))
    x += 1
    if x >= 9:
        x = 0
        y += 1


def game_on(fruits):
    for fruit in fruits:
        fruit_type = [(gem.x, gem.y) for gem in gems if gem.fruit == fruit]
        for x, y in fruit_type:
            if (x-1, y+1) in fruit_type:
                if any(((x+1, y+1), (x-1, y+2),(x-2, y+1),(x-1, y-1
))) in fruit_type:
                    return True
            elif (x-1, y-1) in fruit_type:
                if any(((x+1, y-1), (x-2, y-1),(x-1, y+1),(x-1, y-2)))
in fruit_type:
                    return True
            elif (x+1, y+1) in fruit_type:
                if any(((x+2, y+1), (x+1, y-1),(x+1, y+2),(x-1, y+1)))
in fruit_type:
                    return True
            elif (x+1, y-1) in fruit_type:
                if any(((x+1, y+1), (x+1, y-2),(x+2, y-1),(x-1, y-1)))
in fruit_type:
                    return True
            elif (x-2, y+1) in fruit_type:
                if (x-1, y+1) in fruit_type:
                    return True
            elif (x-2, y-1) in fruit_type:
                if (x-1, y-1) in fruit_type:
                    return True
            elif (x-1, y-2) in fruit_type:
                if (x-1, y-1) in fruit_type:
                    return True
            elif (x+1, y-2) in fruit_type:
                if (x+1, y-1) in fruit_type:
                    return True
    return False

print game_on(fruits)

And here;s a typical printout:


mango
[(3, 0), (0, 1), (3, 1), (5, 1), (6, 1), (8, 1), (1, 2), (2, 2), (5,
2), (1, 4), (4, 4), (6, 4), (2, 5), (4, 5), (5, 5), (2, 6), (3, 6),
(3, 8)] <type 'tuple'># fruit_type and type(fruit_type[2])


got (3, 1), and (2, 2)
(4, 2), (2, 3), (1, 2), (2, 0).If any of these are in fruit type, we
have a match
(1, 2) <type 'tuple'> It's in.# this is from iterating over the tuples
and making sure they are type tuple. We have a match.
##many more matches found###
False # the return from the function

Thanks a lot
Col
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] misunderstanding "any"

Mark Lawrence
On 07/03/2012 03:24, col speed wrote:

> Hello again
> Hope you are all well.
>
> I'm trying to make a "match 3" game, where you have a square grid and
> have to put 3 matching shapes in a row.
> I need a function that tells me if the game is playable, ie. it is
> possible to match 3 shapes by only swapping 2 adjacent shapes.
> I have looked at the co-ordinates and got a list of the "offset
> co-ordinates" needed for the above.
>
> I have a list of coordinates and a list of "lemons" and I want to see
> if *any* lemon coordinate is in the list of coordinates.
> I tried this:
> if any(((x+1, y+1), (x-1, y+2),(x-2, y+1),(x-1, y-1 ))) in fruit_type:
>                      return True
>
> Thinking that if  *any* of the tuples is in fruit_type(a list of
> tuples), then it should return True.
> However, it always equates to False.
> If I iterate through the tuples and see if any are in fruit_type, it
> returns True (when it should).
> I have tried many print statements to make sure what is happening, and
> also to make sure that I am comparing type<tuples>.

Here's the way to find out.

 >>> help(any)
Help on built-in function any in module __builtin__:

any(...)
     any(iterable) -> bool

     Return True if bool(x) is True for any x in the iterable.

 >>> help('in')
Comparisons
***********

[snipped]

The operators ``in`` and ``not in`` test for collection membership.
``x in s`` evaluates to true if *x* is a member of the collection *s*,
and false otherwise.  ``x not in s`` returns the negation of ``x in
s``. The collection membership test has traditionally been bound to
sequences; an object is a member of a collection if the collection is
a sequence and contains an element equal to that object.  However, it
make sense for many other object types to support membership tests
without being a sequence.  In particular, dictionaries (for keys) and
sets support membership testing.

For the list and tuple types, ``x in y`` is true if and only if there
exists an index *i* such that ``x == y[i]`` is true.

For the Unicode and string types, ``x in y`` is true if and only if
*x* is a substring of *y*.  An equivalent test is ``y.find(x) != -1``.
Note, *x* and *y* need not be the same type; consequently, ``u'ab' in
'abc'`` will return ``True``. Empty strings are always considered to
be a substring of any other string, so ``"" in "abc"`` will return
``True``.

Changed in version 2.3: Previously, *x* was required to be a string of
length ``1``.

For user-defined classes which define the ``__contains__()`` method,
``x in y`` is true if and only if ``y.__contains__(x)`` is true.

For user-defined classes which do not define ``__contains__()`` but do
define ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x
== z`` is produced while iterating over ``y``.  If an exception is
raised during the iteration, it is as if ``in`` raised that exception.

Lastly, the old-style iteration protocol is tried: if a class defines
``__getitem__()``, ``x in y`` is true if and only if there is a non-
negative integer index *i* such that ``x == y[i]``, and all lower
integer indices do not raise ``IndexError`` exception. (If any other
exception is raised, it is as if ``in`` raised that exception).

The operator ``not in`` is defined to have the inverse true value of
``in``.

[snipped]

--
Cheers.

Mark Lawrence.

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] misunderstanding "any"

col speed
On 7 March 2012 10:45, Mark Lawrence <[hidden email]> wrote:

> On 07/03/2012 03:24, col speed wrote:
>>
>> Hello again
>> Hope you are all well.
>>
>> I'm trying to make a "match 3" game, where you have a square grid and
>> have to put 3 matching shapes in a row.
>> I need a function that tells me if the game is playable, ie. it is
>> possible to match 3 shapes by only swapping 2 adjacent shapes.
>> I have looked at the co-ordinates and got a list of the "offset
>> co-ordinates" needed for the above.
>>
>> I have a list of coordinates and a list of "lemons" and I want to see
>> if *any* lemon coordinate is in the list of coordinates.
>> I tried this:
>> if any(((x+1, y+1), (x-1, y+2),(x-2, y+1),(x-1, y-1 ))) in fruit_type:
>>                     return True
>>
>> Thinking that if  *any* of the tuples is in fruit_type(a list of
>> tuples), then it should return True.
>> However, it always equates to False.
>>
>
>
> Here's the way to find out.
>
>>>> help(any)
> Help on built-in function any in module __builtin__:
>
> any(...)
>    any(iterable) -> bool
>
>    Return True if bool(x) is True for any x in the iterable.
>
>>>> help('in')
> Comparisons
> ***********
>
> [snipped]
>
>
>
> For the list and tuple types, ``x in y`` is true if and only if there
> exists an index *i* such that ``x == y[i]`` is true.
>
>
> [snipped]
>
> --
> Cheers.
>
> Mark Lawrence.
>
> _______________________________________________
> Tutor maillist  -  [hidden email]
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
Thanks Mark
I looked up help(any), but not help(in)!

I *think* I understand:
Where it says:
"For the list and tuple types, ``x in y`` is true if and only if there
> exists an index *i* such that ``x == y[i]`` is true."

I suppose I am looking for .....an index *i* and *j* such that x[j] == y[i].

Is that right?
cheers
Col
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] misunderstanding "any"

Mark Lawrence
On 07/03/2012 04:36, col speed wrote:

> On 7 March 2012 10:45, Mark Lawrence<[hidden email]>  wrote:
>> On 07/03/2012 03:24, col speed wrote:
>>>
>>> Hello again
>>> Hope you are all well.
>>>
>>> I'm trying to make a "match 3" game, where you have a square grid and
>>> have to put 3 matching shapes in a row.
>>> I need a function that tells me if the game is playable, ie. it is
>>> possible to match 3 shapes by only swapping 2 adjacent shapes.
>>> I have looked at the co-ordinates and got a list of the "offset
>>> co-ordinates" needed for the above.
>>>
>>> I have a list of coordinates and a list of "lemons" and I want to see
>>> if *any* lemon coordinate is in the list of coordinates.
>>> I tried this:
>>> if any(((x+1, y+1), (x-1, y+2),(x-2, y+1),(x-1, y-1 ))) in fruit_type:
>>>                      return True
>>>
>>> Thinking that if  *any* of the tuples is in fruit_type(a list of
>>> tuples), then it should return True.
>>> However, it always equates to False.
>>>
>>
>>
>> Here's the way to find out.
>>
>>>>> help(any)
>> Help on built-in function any in module __builtin__:
>>
>> any(...)
>>     any(iterable) ->  bool
>>
>>     Return True if bool(x) is True for any x in the iterable.
>>
>>>>> help('in')
>> Comparisons
>> ***********
>>
>> [snipped]
>>
>>
>>
>> For the list and tuple types, ``x in y`` is true if and only if there
>> exists an index *i* such that ``x == y[i]`` is true.
>>
>>
>> [snipped]
>>
>> --
>> Cheers.
>>
>> Mark Lawrence.
>>
>> _______________________________________________
>> Tutor maillist  -  [hidden email]
>> To unsubscribe or change subscription options:
>> http://mail.python.org/mailman/listinfo/tutor
> Thanks Mark
> I looked up help(any), but not help(in)!

Note as it's a keyword it has to be in quotes, help('in').

>
> I *think* I understand:
> Where it says:
> "For the list and tuple types, ``x in y`` is true if and only if there
>> exists an index *i* such that ``x == y[i]`` is true."
>
> I suppose I am looking for .....an index *i* and *j* such that x[j] == y[i].
>
> Is that right?

I reckon so although I don't believe that the interactive prompt lies.

 >>> a=tuple(range(10))
 >>> b=tuple(reversed(a))
 >>> a,b
((0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
 >>> a[3] == b[3]
False
 >>> a[5] == b[4]
True

> cheers
> Col
> _______________________________________________
> Tutor maillist  -  [hidden email]
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>

HTH.

--
Cheers.

Mark Lawrence.

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] misunderstanding "any"

col speed
On 7 March 2012 11:50, Mark Lawrence <[hidden email]> wrote:

> On 07/03/2012 04:36, col speed wrote:
>>
>> On 7 March 2012 10:45, Mark Lawrence<[hidden email]>  wrote:
>>>
>>> On 07/03/2012 03:24, col speed wrote:
>
>> I *think* I understand:
>> Where it says:
>> "For the list and tuple types, ``x in y`` is true if and only if there
>>>
>>> exists an index *i* such that ``x == y[i]`` is true."
>>
>>
>> I suppose I am looking for .....an index *i* and *j* such that x[j] ==
>> y[i].
>>
>> Is that right?
>
>
> I reckon so although I don't believe that the interactive prompt lies.
>
>>>> a=tuple(range(10))
>>>> b=tuple(reversed(a))
>>>> a,b
> ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
>>>> a[3] == b[3]
> False
>>>> a[5] == b[4]
> True
>
>> cheers
>> Col
>>
>>

Then we have:


>>> a = tuple(range(10))
>>> b = tuple(reversed(a))

>>> any(a) in b
True

>>> any(b) in a
True

>>> any((a,b)) in (a,b)
False  # I think I understand this now, but I must admit it looks confusing!

Thanks again
Col
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] misunderstanding "any"

Prasad, Ramit-2
> >>> a = tuple(range(10))
> >>> b = tuple(reversed(a))
>
> >>> any(a) in b
> True
>
> >>> any(b) in a
> True
>
> >>> any((a,b)) in (a,b)
> False  # I think I understand this now, but I must admit it looks
> confusing!



I just want to clarify some things. 'any(a) in b' evaluates any(a)
before it evaluates 'x in b'. So in essence 'any(a) in b' is
equivalent to 'True in b'.

The reason why you get True in the first two cases is because
of Python's history where there were no bool types (I could be wrong
on this). At the very least bool types inherit from integer in a
common practice from older languages like C. Hopefully some of my
samples will help explain my point.



>>> a = range(10)
>>> b = tuple( reversed( a ) )
>>> any(a) # Any non-zero value equates to true
True
>>> any(a) in b # True == 1
True
>>> True in b # True == 1
True
>>> any(b) # Any non-zero value equates to true
True
>>> True in a # True == 1
True
>>> True == 1 # Proof that True == 1
True
>>> False == 0 # Proof that False == 0
True
>>> any( (a,b) ) # many non-zero values
True
>>> a = range( 10,20 ) # create a list without 1
>>> b = tuple( reversed( a ) )
>>> any( a ) # still contains non-zero values
True
>>> any( a ) in b # b is missing the value 1 and therefore missing True
False
>>> any( b ) # still contains non-zero values
True
>>> any (b ) in a # a is missing the value 1 and therefore missing True
False
>>> any( (a,b) ) # still contains non-zero values
True
>>> any ( (a,b) ) in ( a,b ) # a and b is missing the value 1
False
>>> any ( (a,b) ) in ( a,b, 1 ) # 1 == True
True


> Thinking that if  *any* of the tuples is in fruit_type(a list of
tuples), then it should return True.

What you want is not any, but probably filter or any + map.



>>> c = zip( a, b )
>>> c
[(10, 19), (11, 18), (12, 17), (13, 16), (14, 15), (15, 14), (16, 13), (17, 12), (18, 11), (19, 10)]
>>> d = ( 11, 18 )
>>> filter( lambda x: d == x, c )
[(11, 18)]
>>>
>>> if filter( lambda x: d == x, c ):
...     print 'True'
...    
True
>>> map( lambda x: x==d, c )
[False, True, False, False, False, False, False, False, False, False]
>>> any( map( lambda x: x==d, c ) )
True


If you are comparing a list of tuples against a list of tuples merely change the above '==' to 'in' and d to be the second list of tuples and it should have similar results

Ramit


Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423

--

This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] misunderstanding "any"

Dave Angel-3
In reply to this post by col speed
On 03/07/2012 12:07 AM, col speed wrote:

> <snip>
> Then we have:
>
>
>>>> a = tuple(range(10))
>>>> b = tuple(reversed(a))
>>>> any(a) in b
> True
>
>>>> any(b) in a
> True
>
>>>> any((a,b)) in (a,b)
> False  # I think I understand this now, but I must admit it looks confusing!
>
> Thanks again
> Col

None of those last three does anything usefully similar to your original
request.  Just because an English phrase makes sense, you can't expect
the equivalent set of keywords to do anything remotely related.

If you insist on using the any function in solving your problem, you'll
have to preprocess your two arrays into a single iterator.  And at that
point, you might as well solve the problem in that loop.

(untested):

def test(a, b):
     for val1 in a:
         for val2 in b:
             if val1 == val2:  return True
     return False
print test(a,b)

Rather than:

def  findinter(a, b):
     res = []
     for val1 in a:
          for val2 in b:
               res.append(val1 == val2)
     return res

print any(findinter(a,b))



--

DaveA

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] misunderstanding "any"

col speed
On 8 March 2012 01:11, Dave Angel <[hidden email]> wrote:

> On 03/07/2012 12:07 AM, col speed wrote:
>>
>> <snip>
>>
>> Then we have:
>>
>>
>>>>> a = tuple(range(10))
>>>>> b = tuple(reversed(a))
>>>>> any(a) in b
>>
>> True
>>
>>>>> any(b) in a
>>
>> True
>>
>>>>> any((a,b)) in (a,b)
>>
>> False  # I think I understand this now, but I must admit it looks
>> confusing!
>>
>> Thanks again
>> Col
>
>
> None of those last three does anything usefully similar to your original
> request.  Just because an English phrase makes sense, you can't expect the
> equivalent set of keywords to do anything remotely related.
>
> If you insist on using the any function in solving your problem, you'll have
> to preprocess your two arrays into a single iterator.  And at that point,
> you might as well solve the problem in that loop.
>
> (untested):
>
> def test(a, b):
>    for val1 in a:
>        for val2 in b:
>            if val1 == val2:  return True
>    return False
> print test(a,b)
>
> Rather than:
>
> def  findinter(a, b):
>    res = []
>    for val1 in a:
>         for val2 in b:
>              res.append(val1 == val2)
>    return res
>
> print any(findinter(a,b))
>
>
>
> --
>
> DaveA
>
Thanks again to everybody for your very clear explanations.
I have done away with any and have defined a function that iterates
through one list and returns True if *i* in the next .
It seems to work every time and also looks a little clearer.
Cheers
Col
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor