Re: Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-05-05 Thread Ethan Furman

On 04/24/2016 08:20 AM, Ian Kelly wrote:

On Sun, Apr 24, 2016 at 1:20 AM, Ethan Furman wrote:



What fun things can Java enums do?


Everything that Python enums can do, plus:

>

--> Planet.EARTH.value
(5.976e+24, 6378140.0)
--> Planet.EARTH.surface_gravity
9.802652743337129

This is incredibly useful, but it has a flaw: the value of each member
of the enum is just the tuple of its arguments. Suppose we added a
value for COUNTER_EARTH describing a hypothetical planet with the same
mass and radius existing on the other side of the sun. [1] Then:

--> Planet.EARTH is Planet.COUNTER_EARTH
True


If using Python 3 and aenum 1.4.1+, you can do

--> class Planet(Enum, settings=NoAlias, init='mass radius'):
... MERCURY = (3.303e+23, 2.4397e6)
... VENUS   = (4.869e+24, 6.0518e6)
... EARTH   = (5.976e+24, 6.37814e6)
... COUNTER_EARTH = EARTH
... @property
... def surface_gravity(self):
... # universal gravitational constant  (m3 kg-1 s-2)
... G = 6.67300E-11
... return G * self.mass / (self.radius * self.radius)
...
--> Planet.EARTH.value
(5.976e+24, 6378140.0)
--> Planet.EARTH.surface_gravity
9.802652743337129
--> Planet.COUNTER_EARTH.value
(5.976e+24, 6378140.0)
--> Planet.COUNTER_EARTH.surface_gravity
9.802652743337129

Planet.EARTH is Planet.COUNTER_EARTH

False



* Speaking of AutoNumber, since Java enums don't have the
instance/value distinction, they effectively do this implicitly, only
without generating a bunch of ints that are entirely irrelevant to
your enum type. With Python enums you have to follow a somewhat arcane
recipe to avoid specifying values, which just generates some values
and then hides them away. And it also breaks the Enum alias feature:

--> class Color(AutoNumber):
... red = default = ()  # not an alias!
... blue = ()
...


Another thing you could do here:

--> class Color(Enum, settings=AutoNumber):
... red
... default = red
... blue
...
--> list(Color)
[, ]
--> Color.default is Color.red
True

--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-24 Thread Michael Selik
On Sun, Apr 24, 2016 at 2:08 PM Steven D'Aprano  wrote:

> On Sun, 24 Apr 2016 04:40 pm, Michael Selik wrote:
> > I think we're giving mixed messages because we're conflating
> "constants" and globals that are expected to change.
>
> When you talk about "state", that usually means "the current state of the
> program", not constants. math.pi is not "state".
>

Perhaps I was unclear. You provided an example of what I was trying to
point out.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-04-24 Thread Ian Kelly
On Sun, Apr 24, 2016 at 10:04 AM, Ethan Furman  wrote:
> On 04/24/2016 08:20 AM, Ian Kelly wrote:
>> * Java doesn't have the hokey notion of enum instances being distinct
>> from their "value". The individual enum members *are* the values.
>> Whereas in Python an enum member is an awkward class instance that
>> contains a value of some other type. Python tries to get away from the
>> C-like notion that enums are ints by making the enum members
>> non-comparable, but then gives us IntEnum as a way to work around it
>> if we really want to. Since Java enums don't depend on any other type
>> for their values, there's nothing inviting the user to treat enums as
>> ints in the first place.
>
>
> How does Java share enums with other programs, computers, and/or languages?

Java enums are serializable using the name. If you need it to be
interoperable with other languages where they're int-based, then you
could attach that value as a field. But that would just be data; you
wouldn't be making that value an integral part of the Java enum just
because some other language does it that way.

>> Because they have the same "value", instead of creating a separate
>> member, COUNTER_EARTH gets defined as an alias for EARTH. To work
>> around this, one would have to add a third argument to the above to
>> pass in an additional value for the sole purpose of distinguishing (or
>> else adapt the AutoNumber recipe to work with this example). This
>> example is a bit contrived since it's generally not likely to come up
>> with floats, but it can easily arise (and in my experience frequently
>> does) when the arguments are of more discrete types. It's notable that
>> the Java enum docs feature this very same example but without this
>> weakness. [2]
>
>
> One reason for this is that Python enums are lookup-able via the value:
>
 Planet(9.80265274333129)
> Planet.EARTH
>
> Do Java enums not have such a feature, or this "feature" totally unnecessary
> in Java?

It's unnecessary. If you want to look up an enum constant by something
other than name, you'd provide a static method or mapping.

I'd argue that it's unnecessary in Python too for the same reason. But
as long as Python enums make a special distinction of their value,
there might as well be a built-in way to do it.

> I could certainly add a "no-alias" feature to aenum.  What would be the
> appropriate value-lookup behaviour in such cases?
>
> - return the first match
> - return a list of matches
> - raise an error
> - disable value-lookups for that Enum

Probably the third or fourth, as I think that value lookup would
generally not be useful in such cases, and it can be overridden if
desired.

> Cool.  The stdlib Enum (and therefore the enum34 backport) is unlikely to
> change much.  However, aenum has a few fun things going on, and I'm happy to
> add more:
>
> - NamedTuple (metaclass-based)
> - NamedConstant (no aliases, no by-value lookups)
> - Enum
>   - magic auto-numbering
>   class Number(Enum, auto=True):
>  one, two, three
>  def by_seven(self):
>  return self.value * 7
>   - auto-setting of attributes
>class Planet(Enum, init='mass radius'):
>  MERCURY = 3.303e23, 2.4397e6
>  EARTH = 5.976e24, 6.37814e6
>  NEPTUNE = 1.024e26, 2.4746e7
>--> Planet.EARTH.mass
>5.976e24

Neat!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-04-24 Thread Ethan Furman

On 04/24/2016 11:27 AM, Chris Angelico wrote:

On Mon, Apr 25, 2016 at 4:12 AM, Ethan Furman wrote:



Values can be anything.  The names are immutable and hashable.


I know they *can* be, because I looked in the docs; but does it make
sense to a human? Sure, we can legally do this:


Well, not me.  ;)


--> class Color(Enum):
... red = 1
... green = 2
... blue = 3
... break_me = [0xA0, 0xF0, 0xC0]
...
--> Color([0xA0, 0xF0, 0xC0])

--> Color([0xA0, 0xF0, 0xC0]).value.append(1)
--> Color([0xA0, 0xF0, 0xC0]).value.append(1)


If you are looking up by value, you have to use the current value. 
Looks like pebkac error to me.  ;)




At some point, we're moving beyond the concept of "enumeration" and
settling on "types.SimpleNamespace".


Sure.  But like most things in Python I'm not going to enforce it.  And 
if somebody somewhere has a really cool use-case for it, more power to 'em.


--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-04-24 Thread Chris Angelico
On Mon, Apr 25, 2016 at 4:12 AM, Ethan Furman  wrote:
> On 04/24/2016 09:47 AM, Chris Angelico wrote:
>
>> I would normally expect enumerated values to be immutable and
>> hashable, but that isn't actually required by the code AIUI. Under
>> what circumstances is it useful to have mutable enum values?
>
>
> Values can be anything.  The names are immutable and hashable.

I know they *can* be, because I looked in the docs; but does it make
sense to a human? Sure, we can legally do this:

>>> class Color(Enum):
... red = 1
... green = 2
... blue = 3
... break_me = [0xA0, 0xF0, 0xC0]
...
>>> Color([0xA0, 0xF0, 0xC0])

>>> Color([0xA0, 0xF0, 0xC0]).value.append(1)
>>> Color([0xA0, 0xF0, 0xC0]).value.append(1)
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/local/lib/python3.6/enum.py", line 241, in __call__
return cls.__new__(cls, value)
  File "/usr/local/lib/python3.6/enum.py", line 476, in __new__
raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: [160, 240, 192] is not a valid Color

but I don't think it's a good thing to ever intentionally do. It's
fine for the Enum class to not enforce it (it means you can use
arbitrary objects as values, and that's fine), but if you actually do
this, then .

At some point, we're moving beyond the concept of "enumeration" and
settling on "types.SimpleNamespace".

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-04-24 Thread Ethan Furman

On 04/24/2016 09:47 AM, Chris Angelico wrote:


I would normally expect enumerated values to be immutable and
hashable, but that isn't actually required by the code AIUI. Under
what circumstances is it useful to have mutable enum values?


Values can be anything.  The names are immutable and hashable.

--
~Ethan~

--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-24 Thread Steven D'Aprano
On Sun, 24 Apr 2016 04:40 pm, Michael Selik wrote:


> I think we're giving mixed messages because we're conflating "constants"
> and globals that are expected to change.

When you talk about "state", that usually means "the current state of the
program", not constants. math.pi is not "state".


> In our case here, I think two clients in the same process sharing state
> might be a feature rather than a bug. Or at least it has the same behavior
> as the current implementation.

I don't think so. Two clients sharing state is exactly what makes thread
programming with shared state so exciting.

Suppose you import the decimal module, and set the global context:

py> import decimal
py> decimal.setcontext(decimal.ExtendedContext)
py> decimal.getcontext().prec = 18
py> decimal.Decimal(1)/3
Decimal('0.33')

Great. Now a millisecond later you do the same calculation:

py> decimal.Decimal(1)/3
Decimal('0.3')


WTF just happened here??? The answer is, another client of the module, one
you may not even know about, has set the global context:

decimal.getcontext().prec = 5

and screwed you over but good.




-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-04-24 Thread Chris Angelico
On Mon, Apr 25, 2016 at 3:54 AM, BartC  wrote:
> On 24/04/2016 17:47, Chris Angelico wrote:
>>
>> On Mon, Apr 25, 2016 at 2:42 AM, Ethan Furman  wrote:

 Easy: allow an empty list to have the same meaning as an empty tuple.
 Every time you have [] in your source code, you're guaranteed to get a
 new (unique) empty list, and then multiple assignment will work.
>>>
>>>
>>>
>>> *sigh*
>>>
>>> Where were you three years ago?  ;)
>>>
>>> Actually, thinking about it a bit more, if we did that then one could not
>>> use an empty list as an enum value.  Why would one want to?  No idea, but
>>> to
>>> make it nearly impossible I'd want a much better reason than a minor
>>> inconvenience:
>>
>>
>> I would normally expect enumerated values to be immutable and
>> hashable,
>
>
> And, perhaps, to be actual enumerations. (So that in the set (a,b,c,d), you
> don't know nor care about the underlying values, except that they are
> distinct.)

Not necessarily; often, the Python enumeration has to sync up with
someone else's, possibly in C. It might not matter that BUTTON_OK is 1
and BUTTON_CANCEL is 2, but you have to make sure that everyone agrees
on those meanings. So when you build the Python module, it's mandatory
that those values be exactly what they are documented as.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-04-24 Thread BartC

On 24/04/2016 17:47, Chris Angelico wrote:

On Mon, Apr 25, 2016 at 2:42 AM, Ethan Furman  wrote:

Easy: allow an empty list to have the same meaning as an empty tuple.
Every time you have [] in your source code, you're guaranteed to get a
new (unique) empty list, and then multiple assignment will work.



*sigh*

Where were you three years ago?  ;)

Actually, thinking about it a bit more, if we did that then one could not
use an empty list as an enum value.  Why would one want to?  No idea, but to
make it nearly impossible I'd want a much better reason than a minor
inconvenience:


I would normally expect enumerated values to be immutable and
hashable,


And, perhaps, to be actual enumerations. (So that in the set (a,b,c,d), 
you don't know nor care about the underlying values, except that they 
are distinct.)


--
Bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-04-24 Thread Chris Angelico
On Mon, Apr 25, 2016 at 2:42 AM, Ethan Furman  wrote:
>> Easy: allow an empty list to have the same meaning as an empty tuple.
>> Every time you have [] in your source code, you're guaranteed to get a
>> new (unique) empty list, and then multiple assignment will work.
>
>
> *sigh*
>
> Where were you three years ago?  ;)
>
> Actually, thinking about it a bit more, if we did that then one could not
> use an empty list as an enum value.  Why would one want to?  No idea, but to
> make it nearly impossible I'd want a much better reason than a minor
> inconvenience:

I would normally expect enumerated values to be immutable and
hashable, but that isn't actually required by the code AIUI. Under
what circumstances is it useful to have mutable enum values?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-04-24 Thread Ethan Furman

On 04/24/2016 09:10 AM, Chris Angelico wrote:

On Mon, Apr 25, 2016 at 2:04 AM, Ethan Furman  wrote:

Unfortunately, the empty tuple tends to be a singleton, so there is no way
to tell that red and default are (supposed to be) the same and blue is
(supposed to be) different:

--> a = b = ()
--> c = ()
--> a is b
True
--> a is c
True

If you have an idea on how to make that work I am interested.


Easy: allow an empty list to have the same meaning as an empty tuple.
Every time you have [] in your source code, you're guaranteed to get a
new (unique) empty list, and then multiple assignment will work.


*sigh*

Where were you three years ago?  ;)

Actually, thinking about it a bit more, if we did that then one could 
not use an empty list as an enum value.  Why would one want to?  No 
idea, but to make it nearly impossible I'd want a much better reason 
than a minor inconvenience:


class Numbers:
   def __init__(self, value=0):
  self.value = value
   def __call__(self, value=None):
  if value is None:
  value = self.value
  self.value = value + 1
  return value

a = Numbers()

class SomeNumbers(Enum):
   one = a()
   two = a()
   five = a(5)
   six = seis = a()

One extra character, and done.

--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-04-24 Thread Chris Angelico
On Mon, Apr 25, 2016 at 2:04 AM, Ethan Furman  wrote:
> Unfortunately, the empty tuple tends to be a singleton, so there is no way
> to tell that red and default are (supposed to be) the same and blue is
> (supposed to be) different:
>
> --> a = b = ()
> --> c = ()
> --> a is b
> True
> --> a is c
> True
>
> If you have an idea on how to make that work I am interested.

Easy: allow an empty list to have the same meaning as an empty tuple.
Every time you have [] in your source code, you're guaranteed to get a
new (unique) empty list, and then multiple assignment will work.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-04-24 Thread Ethan Furman

On 04/24/2016 08:20 AM, Ian Kelly wrote:

On Sun, Apr 24, 2016 at 1:20 AM, Ethan Furman wrote:

On 04/23/2016 06:29 PM, Ian Kelly wrote:



Python enums are great. Sadly, they're still not quite as awesome as Java
enums.



What fun things can Java enums do?


Everything that Python enums can do, plus:

* You can override methods of individual values, not just the class as
a whole. Good for implementing the strategy pattern, or for defining a
default method implementation that one or two values do differently.
In Python you can emulate the same thing by adding the method directly
to the instance dict of the enum value, so this isn't really all that
much of a difference.


All non-dunder methods, at least.


* Java doesn't have the hokey notion of enum instances being distinct
from their "value". The individual enum members *are* the values.
Whereas in Python an enum member is an awkward class instance that
contains a value of some other type. Python tries to get away from the
C-like notion that enums are ints by making the enum members
non-comparable, but then gives us IntEnum as a way to work around it
if we really want to. Since Java enums don't depend on any other type
for their values, there's nothing inviting the user to treat enums as
ints in the first place.


How does Java share enums with other programs, computers, and/or languages?

As far as value-separate-from-instance: if you want/need them to be the 
same thing, mix-in the type:


class Planet(float, Enum):
...

[see below for "no-alias" ideas/questions]

NB: The enum and the value are still different ('is' fails) but equal.


* As a consequence of the above, Java doesn't conflate enum values
with their parameters. The Python enum docs give us this interesting
example of an enum that takes arguments from its declaration:


class Planet(Enum):

... MERCURY = (3.303e+23, 2.4397e6)
... VENUS   = (4.869e+24, 6.0518e6)
... EARTH   = (5.976e+24, 6.37814e6)
... MARS= (6.421e+23, 3.3972e6)
... JUPITER = (1.9e+27,   7.1492e7)
... SATURN  = (5.688e+26, 6.0268e7)
... URANUS  = (8.686e+25, 2.5559e7)
... NEPTUNE = (1.024e+26, 2.4746e7)
... def __init__(self, mass, radius):
... self.mass = mass   # in kilograms
... self.radius = radius   # in meters
... @property
... def surface_gravity(self):
... # universal gravitational constant  (m3 kg-1 s-2)
... G = 6.67300E-11
... return G * self.mass / (self.radius * self.radius)
...

Planet.EARTH.value

(5.976e+24, 6378140.0)

Planet.EARTH.surface_gravity

9.802652743337129

This is incredibly useful, but it has a flaw: the value of each member
of the enum is just the tuple of its arguments. Suppose we added a
value for COUNTER_EARTH describing a hypothetical planet with the same
mass and radius existing on the other side of the sun. [1] Then:


Planet.EARTH is Planet.COUNTER_EARTH

True

Because they have the same "value", instead of creating a separate
member, COUNTER_EARTH gets defined as an alias for EARTH. To work
around this, one would have to add a third argument to the above to
pass in an additional value for the sole purpose of distinguishing (or
else adapt the AutoNumber recipe to work with this example). This
example is a bit contrived since it's generally not likely to come up
with floats, but it can easily arise (and in my experience frequently
does) when the arguments are of more discrete types. It's notable that
the Java enum docs feature this very same example but without this
weakness. [2]


One reason for this is that Python enums are lookup-able via the value:

>>> Planet(9.80265274333129)
Planet.EARTH

Do Java enums not have such a feature, or this "feature" totally 
unnecessary in Java?


I could certainly add a "no-alias" feature to aenum.  What would be the 
appropriate value-lookup behaviour in such cases?


- return the first match
- return a list of matches
- raise an error
- disable value-lookups for that Enum


* Speaking of AutoNumber, since Java enums don't have the
instance/value distinction, they effectively do this implicitly, only
without generating a bunch of ints that are entirely irrelevant to
your enum type. With Python enums you have to follow a somewhat arcane
recipe to avoid specifying values, which just generates some values
and then hides them away. And it also breaks the Enum alias feature:


class Color(AutoNumber):

... red = default = ()  # not an alias!
... blue = ()
...

Color.red is Color.default

False


Unfortunately, the empty tuple tends to be a singleton, so there is no 
way to tell that red and default are (supposed to be) the same and blue 
is (supposed to be) different:


--> a = b = ()
--> c = ()
--> a is b
True
--> a is c
True

If you have an idea on how to make that work I am interested.


Anyroad, I think that covers all my beefs with the way enums are
implemented in Python. Despite the above, they're a great feature, and
I use them and appreciate 

Comparing Python enums to Java, was: How much sanity checking is required for function inputs?

2016-04-24 Thread Ian Kelly
On Sun, Apr 24, 2016 at 1:20 AM, Ethan Furman  wrote:
> On 04/23/2016 06:29 PM, Ian Kelly wrote:
>
>> Python enums are great. Sadly, they're still not quite as awesome as Java
>> enums.
>
>
> What fun things can Java enums do?

Everything that Python enums can do, plus:

* You can override methods of individual values, not just the class as
a whole. Good for implementing the strategy pattern, or for defining a
default method implementation that one or two values do differently.
In Python you can emulate the same thing by adding the method directly
to the instance dict of the enum value, so this isn't really all that
much of a difference.

* Java doesn't have the hokey notion of enum instances being distinct
from their "value". The individual enum members *are* the values.
Whereas in Python an enum member is an awkward class instance that
contains a value of some other type. Python tries to get away from the
C-like notion that enums are ints by making the enum members
non-comparable, but then gives us IntEnum as a way to work around it
if we really want to. Since Java enums don't depend on any other type
for their values, there's nothing inviting the user to treat enums as
ints in the first place.

* As a consequence of the above, Java doesn't conflate enum values
with their parameters. The Python enum docs give us this interesting
example of an enum that takes arguments from its declaration:

>>> class Planet(Enum):
... MERCURY = (3.303e+23, 2.4397e6)
... VENUS   = (4.869e+24, 6.0518e6)
... EARTH   = (5.976e+24, 6.37814e6)
... MARS= (6.421e+23, 3.3972e6)
... JUPITER = (1.9e+27,   7.1492e7)
... SATURN  = (5.688e+26, 6.0268e7)
... URANUS  = (8.686e+25, 2.5559e7)
... NEPTUNE = (1.024e+26, 2.4746e7)
... def __init__(self, mass, radius):
... self.mass = mass   # in kilograms
... self.radius = radius   # in meters
... @property
... def surface_gravity(self):
... # universal gravitational constant  (m3 kg-1 s-2)
... G = 6.67300E-11
... return G * self.mass / (self.radius * self.radius)
...
>>> Planet.EARTH.value
(5.976e+24, 6378140.0)
>>> Planet.EARTH.surface_gravity
9.802652743337129

This is incredibly useful, but it has a flaw: the value of each member
of the enum is just the tuple of its arguments. Suppose we added a
value for COUNTER_EARTH describing a hypothetical planet with the same
mass and radius existing on the other side of the sun. [1] Then:

>>> Planet.EARTH is Planet.COUNTER_EARTH
True

Because they have the same "value", instead of creating a separate
member, COUNTER_EARTH gets defined as an alias for EARTH. To work
around this, one would have to add a third argument to the above to
pass in an additional value for the sole purpose of distinguishing (or
else adapt the AutoNumber recipe to work with this example). This
example is a bit contrived since it's generally not likely to come up
with floats, but it can easily arise (and in my experience frequently
does) when the arguments are of more discrete types. It's notable that
the Java enum docs feature this very same example but without this
weakness. [2]

* Speaking of AutoNumber, since Java enums don't have the
instance/value distinction, they effectively do this implicitly, only
without generating a bunch of ints that are entirely irrelevant to
your enum type. With Python enums you have to follow a somewhat arcane
recipe to avoid specifying values, which just generates some values
and then hides them away. And it also breaks the Enum alias feature:

>>> class Color(AutoNumber):
... red = default = ()  # not an alias!
... blue = ()
...
>>> Color.red is Color.default
False

Anyroad, I think that covers all my beefs with the way enums are
implemented in Python. Despite the above, they're a great feature, and
I use them and appreciate that we have them.

[1] https://en.wikipedia.org/wiki/Counter-Earth
[2] https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-24 Thread Ethan Furman

On 04/23/2016 06:00 PM, Christopher Reimer wrote:


Hmm... What do we use Enum for? :)


from enum import Enum

class Piece(Enum):
king = 'one space, any direction'
queen = 'many spaces, any direction'
bishop = 'many spaces, diagonal'
knight = 'two spaces cardinal, one space sideways, cannot be blocked'
rook = 'many spaces, cardinal'
pawn = 'first move: one or two spaces forward; subsequent moves: 
one space forward; attack: one space diagonal'


--> list(Piece)
[
,
,
,
blocked'>,

,
moves: one space forward; attack: one space diagonal'>,

]

--> p = Piece.bishop
--> p in Piece
True

--> p is Piece.rook
False

--> p is Piece.bishop
True

--
~Ethan~

--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-24 Thread Ethan Furman

On 04/23/2016 06:21 PM, Michael Selik wrote:

On Sat, Apr 23, 2016 at 9:01 PM Christopher Reimer wrote:



Hmm... What do we use Enum for? :)


You can use Enum in certain circumstances to replace int or str constants.
It can help avoid mistyping mistakes and might help your IDE give
auto-complete suggestions. I haven't found a good use for them myself, but
I'd been mostly stuck in Python 2 until recently.


enum34 is the backport, aenum is the turbo charged version.

  https://pypi.python.org/pypi/enum34
  https://pypi.python.org/pypi/aenum

--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-24 Thread Ethan Furman

On 04/23/2016 06:29 PM, Ian Kelly wrote:


Python enums are great. Sadly, they're still not quite as awesome as Java enums.


What fun things can Java enums do?

--
~Ethan~

--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-24 Thread Michael Selik
On Sun, Apr 24, 2016, 1:51 AM Steven D'Aprano  wrote:

> On Sun, 24 Apr 2016 12:34 pm, Michael Torrie wrote:
>
> > There are many aspects to Pythonic programming, not just OOP.  For
> > example using modules to store shared state for your program components
> > is very pythonic, rather than using classes.  A module is kind of like a
> > singleton instance, and still is object-oriented by the way (the module
> > is an object).
>
> I find myself going backwards and forwards on whether or not that is a good
> idea. I think it depends on whether you are writing a library or an
> application.
>
> If you're writing an application, then storing state in module-level
> variables works fine. Your application is, effectively, a singleton, and if
> you try to run it twice, you'll (probably) be running it in two distinct
> processes, so that's okay.
>
> (If you're not, if somehow you perform some sort of trickery where you have
> a single Python interpreter running your script twice in the same process,
> then it will break horribly. But if you can do that, you're living on the
> edge already and can probably deal with it.)
>
> But if you're writing a library, then using module state is a Bad Idea.
> Your
> library may be used by more than one client in the same process, and they
> will conflict over each other's library-level state. "Global variables
> considered harmful."
>

I think we're giving mixed messages because we're conflating "constants"
and globals that are expected to change.

In our case here, I think two clients in the same process sharing state
might be a feature rather than a bug. Or at least it has the same behavior
as the current implementation.

>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-24 Thread Marko Rauhamaa
Steven D'Aprano :

> On Sun, 24 Apr 2016 12:03 pm, Christopher Reimer wrote:
>
>> On 4/23/2016 2:33 PM, Matt Wheeler wrote:
>>> This is still backwards to me. It prevents your classes from being
>>> suitable for restoring a stored game state, not just custom starting
>>> positions (which I think is what Ethan means by custom setups).
>> 
>> I haven't thought that far about saving the game state. I'm under the
>> impression that pickle (or something else) would save and load the
>> instantiated object of each piece. If that's not the case, I'll change
>> the code then.
>
> Pickle will do what you are thinking of, but pickle is not secure and
> involves executing arbitrary code. If you cannot trust the source of
> the pickle, then you should not use it.

You shouldn't use your runtime objects as a storage format. Instead,
design the storage objects separately and translate between runtime and
storage objects as needed.

JSON objects or straight Python dicts are good candidates for overall
storage format. JSON would allow for easy interchange between different
programming languages if need be.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Steven D'Aprano
On Sun, 24 Apr 2016 12:34 pm, Michael Torrie wrote:

> There are many aspects to Pythonic programming, not just OOP.  For
> example using modules to store shared state for your program components
> is very pythonic, rather than using classes.  A module is kind of like a
> singleton instance, and still is object-oriented by the way (the module
> is an object).

I find myself going backwards and forwards on whether or not that is a good
idea. I think it depends on whether you are writing a library or an
application.

If you're writing an application, then storing state in module-level
variables works fine. Your application is, effectively, a singleton, and if
you try to run it twice, you'll (probably) be running it in two distinct
processes, so that's okay.

(If you're not, if somehow you perform some sort of trickery where you have
a single Python interpreter running your script twice in the same process,
then it will break horribly. But if you can do that, you're living on the
edge already and can probably deal with it.)

But if you're writing a library, then using module state is a Bad Idea. Your
library may be used by more than one client in the same process, and they
will conflict over each other's library-level state. "Global variables
considered harmful."



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Steven D'Aprano
On Sun, 24 Apr 2016 12:03 pm, Christopher Reimer wrote:

> On 4/23/2016 2:33 PM, Matt Wheeler wrote:
>> This is still backwards to me. It prevents your classes from being
>> suitable for restoring a stored game state, not just custom starting
>> positions (which I think is what Ethan means by custom setups).
> 
> I haven't thought that far about saving the game state. I'm under the
> impression that pickle (or something else) would save and load the
> instantiated object of each piece. If that's not the case, I'll change
> the code then.

Pickle will do what you are thinking of, but pickle is not secure and
involves executing arbitrary code. If you cannot trust the source of the
pickle, then you should not use it.



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Michael Torrie
On 04/23/2016 09:41 PM, Christopher Reimer wrote:
> I never wanted to learn Java in the first place. My community college 
> couldn't afford to renew the Microsoft site license, which local 
> employers required to learn C/C++ in MS Visual Studio, and all flavors 
> of Java got taught for the programming classes instead. I wanted to 
> learn C/C++. I even wanted to learn assembly language, but I was the 
> only student who showed up for the class and it got cancelled.
> 
> Of course, it probably doesn't help that I got a job in help desk 
> support after I graduated with A.S. degree in Java and never programmed 
> professionally. Thinking like a programmer helped me resolved many IT 
> problems over the last 12 years. My current job in computer security 
> requires tinkering with PowerShell scripts as Python is strictly 
> prohibited in this Windows shop. I have made Python my main programming 
> language at home.

I don't mean to imply that I'm criticizing you for your Java experience!
 I am critical of Java, though.

I'm very glad you've discovered Python and I hope you'll continue to
have fun with it.  I hope you'll take the advice offered by the others
on this thread in stride and hopefully we'll all learn and benefit.

I completely agree with you that learning to think like a programmer is
so helpful in solving all kinds of problems, especially in IT!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Christopher Reimer

On 4/23/2016 8:19 PM, Michael Torrie wrote:

The reason you weren't taught beyond class inheritance is because Java
implements organization only through a class hierarchy. Whole
generations of Java programmers think that program organization is
through classes (a static main method means your code is procedural, by
the way).
I never wanted to learn Java in the first place. My community college 
couldn't afford to renew the Microsoft site license, which local 
employers required to learn C/C++ in MS Visual Studio, and all flavors 
of Java got taught for the programming classes instead. I wanted to 
learn C/C++. I even wanted to learn assembly language, but I was the 
only student who showed up for the class and it got cancelled.


Of course, it probably doesn't help that I got a job in help desk 
support after I graduated with A.S. degree in Java and never programmed 
professionally. Thinking like a programmer helped me resolved many IT 
problems over the last 12 years. My current job in computer security 
requires tinkering with PowerShell scripts as Python is strictly 
prohibited in this Windows shop. I have made Python my main programming 
language at home.


Thank you,

Chris R.
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Michael Torrie
On 04/23/2016 08:32 PM, Christopher Reimer wrote:
> That's the other problem I'm running into. Building a chess engine is a 
> big project. This is probably bigger than the Java XML parser I built 
> from scratch for a college project. I can't seem to find any information 
> on how to build bigger programs. Community college taught me how to 
> program, but it didn't teach me how to go beyond class inheritance.

The reason you weren't taught beyond class inheritance is because Java
implements organization only through a class hierarchy. Whole
generations of Java programmers think that program organization is
through classes (a static main method means your code is procedural, by
the way).

Learn about Python namespaces and how to use them.  I guess it just
comes with experience, a lot of trial and a lot of error.  And checking
on how others are doing it.  Take a look at examples from the Python
standard library, as well as other projects.  For example, Beautiful
Soup.  Not that you have to understand their code, but take a look at
how they organize things.

In my mind namespaces matter more than files as an organizational tool.
 Because namespaces are my primary organization, I will put multiple
class definitions in the same file (if they belong in the same
namespace), so they can be imported from the same module. If the classes
and functions get more complicated, I can separate them into their own
submodules and wrap them all up in one Python package (like a module but
more flexible and has submodules).

The nice thing about building with Python is you can start with one
thing, like a module, and convert it to a package later on as needed.


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Christopher Reimer

On 4/23/2016 7:34 PM, Michael Torrie wrote

Procedural programming does not necessarily mean BASIC-style goto hell.
Not sure why you would think that.  In fact that's not really what
procedural programming is about.


I mentioned several messages back that I spent two years writing 
procedural scripts AND translating BASIC games into Python, which can be 
goto hell if the program has a drop-down structure that makes sense only 
from following the entry point of the goto statement (see link for example).


http://www.atariarchives.org/basicgames/showpage.php?page=9

I try to follow the BASIC program structure as closely as possible, get 
it working in Python, and use pylint to make my code PEP8-compliant. 
Pylint frequently complains about exceeding a dozen if branches in the 
main function. I then create helper functions to reduce the if branches. 
Sometimes that makes the Python version either shorter or longer than 
the original BASIC program.


Thank you,

Chris R.
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Michael Torrie
On 04/23/2016 07:45 PM, Christopher Reimer wrote:
> I had to confront all the bad habits I brought over Java and change my 
> code to be more Pythonic. This is where I started having fun, learning 
> the tricks and collapsing multi-line code into a single line code. I've 
> learned more about Python in the few weeks than I had in two years of 
> writing procedural scripts and translating BASIC goto hell.

Procedural programming does not necessarily mean BASIC-style goto hell.
Not sure why you would think that.  In fact that's not really what
procedural programming is about.  However, Mr. Selik wasn't advocating
procedural programming at all.  Not defining a class does not make your
code precdural.  But using classes does not mean your code is *not*
procedural. If you are using an event-driven framework then I will say,
yes your code is not procedural.

There are many aspects to Pythonic programming, not just OOP.  For
example using modules to store shared state for your program components
is very pythonic, rather than using classes.  A module is kind of like a
singleton instance, and still is object-oriented by the way (the module
is an object).  Sadly Java really messed up people by using classes as a
namespace mechanism.  That was quite a mistake.  Really messed with
people's expectations of OOP.

I would say that pythonic programming involves defining classes when
it's appropriate, and not doing so when something else will work just as
well and be simpler.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Christopher Reimer

On 4/23/2016 6:38 PM, Michael Selik wrote:


Why so many files? Python can easily support thousands of lines in a
file. If it's just one file any text editor can do a quick find-replace.


That goes back to the Java convention of having one class per file. It 
took a while to convince myself that mixing classes and functions in a 
single file was okay. Once I finished cleaning up the code for this 
round, I'll merge four files into one file (~500 lines) and have four 
files (main.py, display.py, engine.py and utility.py).



Or just use one file to keep things easier. But, yes, I agree a module
of constants is appropriate for bigger projects.


That's the other problem I'm running into. Building a chess engine is a 
big project. This is probably bigger than the Java XML parser I built 
from scratch for a college project. I can't seem to find any information 
on how to build bigger programs. Community college taught me how to 
program, but it didn't teach me how to go beyond class inheritance.


Thank you,

Chris R.
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Christopher Reimer

On 4/23/2016 6:29 PM, Ian Kelly wrote:
Python enums are great. Sadly, they're still not quite as awesome as 
Java enums.


I remember enums more from C than Java. Although I haven't used them 
much in either language. I'm planning to immerse myself back into C via 
Cython. Depending on far I get into this chess program, I might need a 
speed boost here and there.


Thank you,

Chris R.

--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Christopher Reimer

On 4/23/2016 2:33 PM, Matt Wheeler wrote:

This is still backwards to me. It prevents your classes from being
suitable for restoring a stored game state, not just custom starting
positions (which I think is what Ethan means by custom setups).


I haven't thought that far about saving the game state. I'm under the 
impression that pickle (or something else) would save and load the 
instantiated object of each piece. If that's not the case, I'll change 
the code then.


The sanity check does have an exemption for pawn promotion, where a pawn 
reaching the other side of the board can be promoted to another piece 
(typically a queen). I played Sargon II chess on the Commodore 64 for 
five years as a teenager. The worst game I ever won was when the 
computer had nine queens on the board. I thought the computer was 
cheating outrageously but a chess rule book confirmed that promotion was 
a legit move.


https://en.wikipedia.org/wiki/Promotion_(chess)

If I need to add an exemption to custom plays, I'll add it then. Right 
now I'm cleaning up the existing code from all the bad Java habits.


Thank you,

Chris R.
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Christopher Reimer

On 4/22/2016 1:40 PM, Michael Selik wrote:

Frankly, for someone coming from Java, the best advice is to not write any
classes until you must. Of course classes in Python are very useful. It's
just that your Java habits are unnecessary and often counter-productive.


I disagree. I wrote procedural scripts and translated old BASIC games 
into Python for two years. One day I came across a Python book that 
described the principles of subclassing from a base class for chess 
pieces, but there was no code to demonstrate the process. I had no 
problem creating the Python classes. That's how my research project got 
started to build a chess engine. If you ever check the academic 
literature for chess programming, this research project could turn into 
a lifelong endeavor.


I had to confront all the bad habits I brought over Java and change my 
code to be more Pythonic. This is where I started having fun, learning 
the tricks and collapsing multi-line code into a single line code. I've 
learned more about Python in the few weeks than I had in two years of 
writing procedural scripts and translating BASIC goto hell.


Thank you,

Chris R.
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Michael Selik
On Sat, Apr 23, 2016 at 9:31 PM Christopher Reimer <
christopher_rei...@icloud.com> wrote:

> On 4/21/2016 10:25 PM, Stephen Hansen wrote:
> >
> > Why not, 'color in ("black", "white")'?
>
> Checkers seems popular around here. What if I want to change "white" to
> "red," as red and black is a common color scheme for checkers. Do I
> change a single constant variable or replace all the occurrences in the
> files?
>

Why so many files? Python can easily support thousands of lines in a file.
If it's just one file any text editor can do a quick find-replace.

That said, it's easy to make some global ``red = 'red'``.

Some of these constants are shortcuts. Instead of writing slice(0, 16)
> or slice(48, 64), and getting the two confused, I write
> const['board_bottom'] or const['board_top'], respectively, when I want
> to pull the correct set of positions from coordinates list.
>

Why hide these things in a dict ``const`` instead of just making them
top-level variables in the module themselves?  ``board_top = slice(48,
64)``

> That said, if you're wanting to share constants across different parts
> > of your code, use a module.
>

Or just use one file to keep things easier. But, yes, I agree a module of
constants is appropriate for bigger projects.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Ian Kelly
On Sat, Apr 23, 2016 at 7:00 PM, Christopher Reimer
 wrote:
> On 4/21/2016 9:46 PM, Ethan Furman wrote:
>>
>> Oh! and Enum!!!  ;)
>
>
> OMG! I totally forgot about Enum. Oh, look. Python supports Enum. Now I
> don't have to roll my own!
>
> Hmm... What do we use Enum for? :)

Python enums are great. Sadly, they're still not quite as awesome as Java enums.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Christopher Reimer

On 4/21/2016 10:25 PM, Stephen Hansen wrote:


Why not, 'color in ("black", "white")'?


Checkers seems popular around here. What if I want to change "white" to 
"red," as red and black is a common color scheme for checkers. Do I 
change a single constant variable or replace all the occurrences in the 
files?


Some of these constants are shortcuts. Instead of writing slice(0, 16) 
or slice(48, 64), and getting the two confused, I write 
const['board_bottom'] or const['board_top'], respectively, when I want 
to pull the correct set of positions from coordinates list.



That said, if you're wanting to share constants across different parts
of your code, use a module.


I did that at first, made it into a dictionary class and added 
ConfigParser to the mix. I had a lot of fun putting that one together. 
However, as I refactor my code further as I learn new things, it will 
probably get changed or removed. Being a research project, I'm willing 
to dive into every rabbit hole that I come across to learn Python properly.


Thank you,

Chris R.
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Michael Selik
On Sat, Apr 23, 2016 at 9:01 PM Christopher Reimer <
christopher_rei...@icloud.com> wrote:

> On 4/21/2016 9:46 PM, Ethan Furman wrote:
> > Oh! and Enum!!!  ;)
>
> OMG! I totally forgot about Enum. Oh, look. Python supports Enum. Now I
> don't have to roll my own!
>
> Hmm... What do we use Enum for? :)
>

You can use Enum in certain circumstances to replace int or str constants.
It can help avoid mistyping mistakes and might help your IDE give
auto-complete suggestions. I haven't found a good use for them myself, but
I'd been mostly stuck in Python 2 until recently.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Christopher Reimer

On 4/21/2016 9:46 PM, Ethan Furman wrote:

Oh! and Enum!!!  ;)


OMG! I totally forgot about Enum. Oh, look. Python supports Enum. Now I 
don't have to roll my own!


Hmm... What do we use Enum for? :)

Thank you,

Chris R.

--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-23 Thread Matt Wheeler
On 22 April 2016 at 04:11, Christopher Reimer
 wrote:
> On 4/21/2016 7:10 PM, Ethan Furman wrote:
>>> I do plan to incorporate a sanity test in each Piece class to validate
>>> the initial position value. Pawns have 16 specific positions. Bishop,
>>> Knight and Rook each have four specific positions. King and Queen each
>>> have two specific positions. An invalid value will raise an exception.
>>
>> This will make it so you cannot use your PieceFactory for custom setups.
>
> The sanity check won't be in the PieceFactory, but in the Piece class as an
> interface and each Piece subclass will implement the correct positions for
> comparison.

This is still backwards to me. It prevents your classes from being
suitable for restoring a stored game state, not just custom starting
positions (which I think is what Ethan means by custom setups).

If you need to put sanity checking in your initialisation at all it
should be at some higher level, probably in a method named something
like `start_chess_game`. But really I'd suggest just writing tests for
that method to make sure it's doing the right thing.

On the other hand (and I'm sure you've already thought of this) it
probably does make sense to put piece move validation in to each of
the piece classes: you could even have some fun with it...

def move_straight(old, new):
if old[0] == new[0] or old[1] == new[1]:
return True

def move_diag(old, new):
diff_x = abs(old[0] - new[0])
diff_y = abs(old[1] - new[1])
if diff_x == diff_y:
return True

class Piece:
   ...
def move(self, new):
if self.validate_move(new):
# do the move
...
else: raise IllegalMove('or something')

class Queen(Piece):
def validate_move(self, new):
return any((test(self.position, new) for test in
(move_straight, move_diag)))


Ok I'll stop before I get too carried away... This is completely
untested so bugs will abound I'm sure :)

-- 
Matt Wheeler
http://funkyh.at
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-22 Thread Michael Selik
On Fri, Apr 22, 2016, 1:26 AM Stephen Hansen  wrote:

> On Thu, Apr 21, 2016, at 08:33 PM, Christopher Reimer wrote:
> > On 4/21/2016 7:20 PM, Stephen Hansen wrote:
> > > I... that... what... I'd forget that link and pretend you never went
> > > there. Its not helpful.
> >
> > I found it on the Internet, so it must be true -- and Pythonic at that!
>
> My advice is to not look at that site further. I can't count the number
> of things that are just... not useful or helpful.
>
> Directly translating the Gang of Four Design Pattern book to Python
> doesn't generally result in useful ideas, except in certain abstractions
> like the visitor pattern when you're designing big systems.
>

Frankly, for someone coming from Java, the best advice is to not write any
classes until you must. Of course classes in Python are very useful. It's
just that your Java habits are unnecessary and often counter-productive.

Just make some globals and some functions. Heck, even write procedurally
for a while. Free yourself from the Kingdom of Nouns.
http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html

>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-21 Thread Stephen Hansen
On Thu, Apr 21, 2016, at 08:33 PM, Christopher Reimer wrote:
> On 4/21/2016 7:20 PM, Stephen Hansen wrote:
> > I... that... what... I'd forget that link and pretend you never went
> > there. Its not helpful.
> 
> I found it on the Internet, so it must be true -- and Pythonic at that!

My advice is to not look at that site further. I can't count the number
of things that are just... not useful or helpful. 

Directly translating the Gang of Four Design Pattern book to Python
doesn't generally result in useful ideas, except in certain abstractions
like the visitor pattern when you're designing big systems. 



> 
> > What's the contents of this big dictionary that has everything in it 
> > for some reason?
> 
> Keep in mind that I'm coming from a Java background (not by choice) with 
> a smattering of C programming. I initially had ALL THESE CONSTANTS in 
> different parts of my code and couldn't easily use them across different 
> modules. I didn't like all these constants, created a singleton class 
> that uses ConfigParser, dumped everything into a .ini file, and accessed 
> from in each module. As I learn to write Pythonic code, the constants 
> may go away. Switching from my original code to the factory method 
> eliminated a half-dozen constants.

I'm not criticizing, I'm *asking* in the hopes you'll explain what
you're doing better, so I can understand and give advice that's more
relevant: I don't understand what it is you're doing with the VARS or
const dictionary. Even with your explanation here, I don't get it. 

Why do you need to read VARS["COLOR_BLACK"] or the new
const["COLOR_BLACK"} from a configuration file? How is this stuff
configurable? 

Why not, 'color in ("black", "white")'?

The only reason I can think of why you'd want to read what is "black" or
"white" out of a configuration file is internationalization, and if
that's your aim, there's a couple really good projects I can recommend
that solve that issue better. 

I can't think of any reason why you'd want a structure like:
struct = {}
struct["COLOR_BLACK"] = "black"
struct["COLOR_WHITE"] = "white"

"black" is a perfectly good way to express "black", you have this
indirection/abstraction for a reason I don't understand. Granted, maybe
this is a heavy javaism, and I'm utterly ignorant of Java, but my C/C++
mind can't think of a reason for this either.

That said, if you're wanting to share constants across different parts
of your code, use a module.

Create a module, say, things.py, that itself doesn't import other
things, and it says:

black = "Black"
white = "White"

(Bear in mind I still don't know why you want or need this indirection)

Then you "import things" and refer to those constants as things.black,
things.white.

You can then "if color in (things.black, things.white)". Maybe even "if
color in things.colors" if in your things file you have things = (black,
white).

Modules are great for sharing information. The admonition of GLOBALS R
BAD is not as strong in Python as you find in some other languages.
(Don't take that to mean GLOBALS R GUD, granted. Passing state is best
when it makes sense).

--S
m e @ i x o k a i . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-21 Thread Ethan Furman

On 04/21/2016 08:33 PM, Christopher Reimer wrote:

On 4/21/2016 7:20 PM, Stephen Hansen wrote:



Keep in mind that I'm coming from a Java background (not by choice) with
a smattering of C programming.


A refugee!  Water!  Food!  import this!!  :)

Oh!  and Enum!!!  ;)

--
~Ethan~

--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-21 Thread Christopher Reimer

On 4/21/2016 7:20 PM, Stephen Hansen wrote:
Whyyy are you using getattr? Something wrong with 
PieceFactory.factory(color, piece, position)? (Or, better yet, yield 
piece_factory(color, piece, position) where piece_factory is just a 
function)


Because the example I found used it, I implemented it, and it worked in 
my code. Based on feedback that I gotten from this list, I'll go back 
and clean it up.



I... that... what... I'd forget that link and pretend you never went
there. Its not helpful.


I found it on the Internet, so it must be true -- and Pythonic at that!

What's the contents of this big dictionary that has everything in it 
for some reason?


Keep in mind that I'm coming from a Java background (not by choice) with 
a smattering of C programming. I initially had ALL THESE CONSTANTS in 
different parts of my code and couldn't easily use them across different 
modules. I didn't like all these constants, created a singleton class 
that uses ConfigParser, dumped everything into a .ini file, and accessed 
from in each module. As I learn to write Pythonic code, the constants 
may go away. Switching from my original code to the factory method 
eliminated a half-dozen constants.


Thank you,

Chris R.
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-21 Thread Christopher Reimer

On 4/21/2016 7:10 PM, Ethan Furman wrote:

I do plan to incorporate a sanity test in each Piece class to validate
the initial position value. Pawns have 16 specific positions. Bishop,
Knight and Rook each have four specific positions. King and Queen each
have two specific positions. An invalid value will raise an exception.


This will make it so you cannot use your PieceFactory for custom setups.



The sanity check won't be in the PieceFactory, but in the Piece class as 
an interface and each Piece subclass will implement the correct 
positions for comparison.


Thank you,

Chris R.
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-21 Thread Christopher Reimer

On 4/21/2016 6:54 PM, Tim Chase wrote:


I'd simplify this code to something like

   class PieceFactory(object):
 @staticmethod
 def factory(color, piece, position):
   try:
 return {
   'Bishop': Bishop,
   'King': King,
   'Knight': Knight,
   'Pawn': Pawn,
   'Queen': Queen,
   'Rook': Rook,
   }[piece](color, position)
   except KeyError:
 raise PieceException(...)


I like this better. I'll probably remove the try/except and let the 
KeyError filter up.


Thanks,

Chris R.
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-21 Thread Steven D'Aprano
On Fri, 22 Apr 2016 11:34 am, Christopher Reimer wrote:

> Greetings,
> 
> Thanks to everyone for providing feedback. Here's my revised code to
> generate a set of chess pieces.

> class PieceFactory(object):
> 
>  def factory(color, piece, position):
>  if piece == 'Bishop':
>  return Bishop(color, position)
>  if piece == 'King':
>  return King(color, position)
>  if piece == 'Knight':
>  return Knight(color, position)
>  if piece == 'Pawn':
>  return Pawn(color, position)
>  if piece == 'Queen':
>  return Queen(color, position)
>  if piece == 'Rook':
>  return Rook(color, position)
> 
>  raise PieceException('No valid Piece object for factory,
> got {}'
>   ' instead'.format(piece))
> 
>  factory = staticmethod(factory)


Eww :-)

Creating an entire class with no state just to hold one method is an abuse
of classes. If your class doesn't include both state (data) and behaviour
(methods), it probably shouldn't be a class.


class King: ...
class Queeen: ... 
# etc.

PIECES = dict((piece.__name__, piece) for piece in 
  [King, Queen, Bishop, Knight, Rook, Pawn])

def make_piece(color, name, position):
name = name.title()  # Accept 'king', 'KING', 'King' etc.
P = PIECES.get(name, None)
if P is None:
raise PieceException('unknown name %r' % name)
return P(color, position)



> def generate_set(color, pieces, positions):
>  for piece, position in zip(pieces, positions):
>  yield getattr(PieceFactory, 'factory')(color, piece, position)


def generate_pieces(color, names, positions):
for name, position in zip(names, positions):
yield make_piece(color, name, position)




-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-21 Thread Tim Chase
On 2016-04-21 18:34, Christopher Reimer wrote:
> class PieceFactory(object):
> 
>  def factory(color, piece, position):
>  if piece == 'Bishop':
>  return Bishop(color, position)
>  if piece == 'King':
>  return King(color, position)
>  if piece == 'Knight':
>  return Knight(color, position)
>  if piece == 'Pawn':
>  return Pawn(color, position)
>  if piece == 'Queen':
>  return Queen(color, position)
>  if piece == 'Rook':
>  return Rook(color, position)
> 
>  raise PieceException('No valid Piece object for
> factory, got {}'
>   ' instead'.format(piece))
> 
>  factory = staticmethod(factory)

I'd simplify this code to something like

  class PieceFactory(object):
@staticmethod
def factory(color, piece, position):
  try:
return {
  'Bishop': Bishop,
  'King': King,
  'Knight': Knight,
  'Pawn': Pawn,
  'Queen': Queen,
  'Rook': Rook,
  }[piece](color, position)
  except KeyError:
raise PieceException(...)

which removes some of the redundancy.  I might even be tempted to
simply ignore the exception and let the KeyError percolate up the
call-stack if someone calls it with an unknown piece/key, rather
than converting it into a PieceException.

-tkc




-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-21 Thread Stephen Hansen
On Thu, Apr 21, 2016, at 06:34 PM, Christopher Reimer wrote:
> class PieceFactory(object):
> 
>  def factory(color, piece, position):
>  if piece == 'Bishop':
>  return Bishop(color, position)
>  if piece == 'King':
>  return King(color, position)
>  if piece == 'Knight':
>  return Knight(color, position)
>  if piece == 'Pawn':
>  return Pawn(color, position)
>  if piece == 'Queen':
>  return Queen(color, position)
>  if piece == 'Rook':
>  return Rook(color, position)

This whole section is begging for a dictionary. Like...

_PIECE_TYPES= {"Bishop": Bishop, "King": King, ...]

class PieceFactory(object):
def factory(color, piece, position):
klass = __PIECE_TYPES.get(piece)
if klass is None:
raise PieceException("...")

return klass(color, position)

Or something like that.

That said, I'm not sure why its not just a function that does the same
thing. Why is it in a class that only does one thing? You never even
instantiate it.

> def generate_set(color, pieces, positions):
>  for piece, position in zip(pieces, positions):
>  yield getattr(PieceFactory, 'factory')(color, piece, position)

Whyyy are you using getattr? Something wrong with
PieceFactory.factory(color, piece, position)? (Or, better yet, yield
piece_factory(color, piece, position) where piece_factory is just a
function)

> I got the factory method from here: 
> http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Factory.html

I... that... what... I'd forget that link and pretend you never went
there. Its not helpful.

> Finally, VARS['VARIABLE_NAME'] got change to const['variable_name']. 
> Should smell better.

I don't know that this changes anything about the small at all. What's
the contents of this big dictionary that has everything in it for some
reason?

That said, dear god, 'piece' doesn't look like an english word to me
anymore. I've never suffered semantic satiation from text before.

--Stephen
m e @ i x o k a i . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-21 Thread Ethan Furman

On 04/21/2016 06:34 PM, Christopher Reimer wrote:


class PieceFactory(object):

> [...]

Better.


I do plan to incorporate a sanity test in each Piece class to validate
the initial position value. Pawns have 16 specific positions. Bishop,
Knight and Rook each have four specific positions. King and Queen each
have two specific positions. An invalid value will raise an exception.


This will make it so you cannot use your PieceFactory for custom setups.

--
~Ethan~

--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-21 Thread Christopher Reimer

Greetings,

Thanks to everyone for providing feedback. Here's my revised code to 
generate a set of chess pieces.



class PieceFactory(object):

def factory(color, piece, position):
if piece == 'Bishop':
return Bishop(color, position)
if piece == 'King':
return King(color, position)
if piece == 'Knight':
return Knight(color, position)
if piece == 'Pawn':
return Pawn(color, position)
if piece == 'Queen':
return Queen(color, position)
if piece == 'Rook':
return Rook(color, position)

raise PieceException('No valid Piece object for factory, 
got {}'

 ' instead'.format(piece))

factory = staticmethod(factory)


def generate_set(color, pieces, positions):

for piece, position in zip(pieces, positions):
yield getattr(PieceFactory, 'factory')(color, piece, position)


The input values for 'pieces' and 'positions' are 16-item lists zipped 
together to produce a piece name and a position coordinate for the 
factory method. With slight modifications to the code, the factory 
method could also return checker pieces.


I got the factory method from here: 
http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Factory.html


I do plan to incorporate a sanity test in each Piece class to validate 
the initial position value. Pawns have 16 specific positions. Bishop, 
Knight and Rook each have four specific positions. King and Queen each 
have two specific positions. An invalid value will raise an exception.


Finally, VARS['VARIABLE_NAME'] got change to const['variable_name']. 
Should smell better.


Thanks,

Chris R

--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-20 Thread Stephen Hansen
On Tue, Apr 19, 2016, at 11:09 PM, Ethan Furman wrote:
> On 04/19/2016 10:51 PM, Stephen Hansen wrote:
> > I use 1) more to be less 'nicer' and more, er, 'more specific'. Since I
> > don't like exceptions to rise to the user level where niceness is
> > needed.
> 
> Yeah, that's a better phrasing for (1); I meant more appropriate or 
> informative, such as swapping an internal error (such as KeyError) for a 
> more meaningful FieldNotFound error (or whatever) -- largely library 
> code concerns.

Yeah, and what the OP is doing is going the exact opposite-- from a
more-specific exception (KeyError) to a more generic one (Exception).

To me that's (usually) an anti-pattern. 

--S
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-20 Thread Ethan Furman

On 04/19/2016 10:51 PM, Stephen Hansen wrote:


But that's a fuzzy question, there's no solid and clear answer. Did you
see Ethan's response? I largely agree with his trinity:

On Sun, Apr 17, 2016, at 10:26 PM, Ethan Furman wrote:

I sanity check for three reasons:

1) raise a nicer error message

2) keep the point of failure close to the error

3) the consequences of bad data are Bad Bad Things (tm)


With a 4)th that exceptions aren't for users, only programmers. But
ultimately, I'd rather a user see an exception if something weird goes
wrong because they can send it to me and I can diagnose it and push an
update. So I also:

4) Attempt to make sure all user errors result in user error messages,
not exceptions.

Note, 1) doesn't mean I always raise a nicer message, it means if
"KeyError" is ambiguious or odd, I raise a better and more informative
one. But you're getting nothing swapping out KeyError for
Exception(lotsofwords).

I use 1) more to be less 'nicer' and more, er, 'more specific'. Since I
don't like exceptions to rise to the user level where niceness is
needed.


Yeah, that's a better phrasing for (1); I meant more appropriate or 
informative, such as swapping an internal error (such as KeyError) for a 
more meaningful FieldNotFound error (or whatever) -- largely library 
code concerns.


--
~Ethan~

--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-19 Thread Stephen Hansen
On Sun, Apr 17, 2016, at 12:34 PM, Christopher Reimer wrote:
>  if color not in [VARS['COLOR_BLACK'], VARS['COLOR_WHITE']]:
>  raise Exception("Require \'{}\' or \'{}\' for input value, got 
> \'{}\' instead.".format(VARS['COLOR_BLACK'], VARS['COLOR_WHITE'], color))

Do you think it likely you'll receive a 'color' value not in the list of
black and white? Are you accepting colors from users? If you are, I'd
sanity check *at user input*. Users are crazy, sanitize and check the
heck out of their stuff.

Your code, though? Your time and effort is better spent putting in a
docstring documenting what's valid in color, and if some other coder
puts in red, why, they'll get a KeyError, and it'll point to precisely
what line is wrong, and be able to figure it out.

Unit tests are where you try feeding invalid data into functions and see
how they react-- and the correct reaction to bad data is usually
exceptions. In this case, a KeyError thrown by [VARS['COLOR_BLACK'],
VARS['COLOR_WHITE']][color] is more descriptive then your verbose
Exception.

(What's with the VARS business? Something smells bad there. You're doing
something weird there)

> How much sanity checking is too much in Python?

IMHO, you've got too much.

But that's a fuzzy question, there's no solid and clear answer. Did you
see Ethan's response? I largely agree with his trinity:

On Sun, Apr 17, 2016, at 10:26 PM, Ethan Furman wrote:
> I sanity check for three reasons:
> 
> 1) raise a nicer error message
> 
> 2) keep the point of failure close to the error
> 
> 3) the consequences of bad data are Bad Bad Things (tm)

With a 4)th that exceptions aren't for users, only programmers. But
ultimately, I'd rather a user see an exception if something weird goes
wrong because they can send it to me and I can diagnose it and push an
update. So I also:

4) Attempt to make sure all user errors result in user error messages,
not exceptions.

Note, 1) doesn't mean I always raise a nicer message, it means if
"KeyError" is ambiguious or odd, I raise a better and more informative
one. But you're getting nothing swapping out KeyError for
Exception(lotsofwords). 

I use 1) more to be less 'nicer' and more, er, 'more specific'. Since I
don't like exceptions to rise to the user level where niceness is
needed.

--Stephen
m e @ i x o k a i . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-19 Thread Michael Selik
On Tue, Apr 19, 2016 at 11:23 PM Christopher Reimer <
christopher_rei...@icloud.com> wrote:

> On 4/19/2016 1:02 AM, Michael Selik wrote:
>
> > Why relocate rather than remove? What message would you provide that's
> > better than ``KeyError: 42`` with a traceback that shows exactly which
> > dictionary is being used and how?
>
> I think you misread my code. No dictionary exception occurs in the
> sanity checks. Below is the full function with the revised sanity check
> for positions that compares the input list with the two valid lists of
> board positions.
>

Perhaps I did misread it. What is the purpose of the "sanity check"? If
it's not obvious I suggest revising the code rather than adding comments.

The first time I read your code, I thought the check was designed to avoid
the possibility of a KeyError a few lines later. My suggestion was to
simply allow bad inputs to cause KeyErrors and not clutter your code. This
second time I'm reading, it seems to be a sort of boundary check, but using
``in`` which would cause a bug... Did you mean to use an inequality?


> > I meant, what goes wrong if the number of positions input is other than
> > 16? Without these "sanity" checks, your functions might be reusable in,
> > say, a checkers game.
>
> I have no desire to write reusable code for two
> similar but different games at the same time.
>

Reusability is a nice side-effect of fewer "sanity checks". Other goals are
clarity, efficiency, and productivity.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-19 Thread Chris Angelico
On Wed, Apr 20, 2016 at 12:20 PM, Christopher Reimer
 wrote:
> I think you misread my code. No dictionary exception occurs in the sanity
> checks. Below is the full function with the revised sanity check for
> positions that compares the input list with the two valid lists of board
> positions.
>
>
> def generate_set(color, positions):
>
> if positions not in [VARS['COORDINATES'][VARS['BOARD_BOTTOM']],
>  VARS['COORDINATES'][VARS['BOARD_TOP']]]:
> raise Exception("List for positions contains no valid coordinates, "
> "got {} instead.".format(positions))
>
> # generate objects according to color and position
> for position in positions:
> rank, file = position
> if rank in VARS['RANK_NOBILITY']:
> if file in VARS['FILE_ROOK']:
> yield Rook(color, position)
> elif file in VARS['FILE_BISHOP']:
> yield Bishop(color, position)
> elif file in VARS['FILE_KNIGHT']:
> yield Knight(color, position)
> elif file is VARS['FILE_QUEEN']:
> yield Queen(color, position)
> elif file is VARS['FILE_KING']:
> yield King(color, position)
> else:
> yield Pawn(color, position)
>

If you nuke the check at the beginning, what happens? (By the way, I
don't like this shouty "VARS" thing you have going on. It makes it
hard to skim the code. I'm not entirely sure what your initial "not
in" check is even doing.) You seem to have two slightly different ways
of checking things: first something about BOARD_TOP and BOARD_BOTTOM,
and then something else about RANK_NOBILITY and... everything else. It
looks to me like all you need is to have a second check for
RANK_PAWNS, and then raise an exception if it's neither of those. Then
you don't need to pre-check, and the rules aren't split into two
places.

But if I were doing this, I'd make it far more data-driven.

starting_positions = {
VARS['FILE_ROOK']: Rook,
VARS['FILE_BISHOP']: Bishop,
...
}

Or, even better, tie that to the definitions of your classes, in some
way. (Metaprogramming is great here.) Then your code doesn't need an
if/elif tree; you can generate starting positions easily by just
looking up your table.

BTW, it's usually best to not raise Exception, but a custom subclass
of it. But I'm going to assume that this is just an example.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-19 Thread Christopher Reimer

On 4/19/2016 1:02 AM, Michael Selik wrote:


Why relocate rather than remove? What message would you provide that's
better than ``KeyError: 42`` with a traceback that shows exactly which
dictionary is being used and how?


I think you misread my code. No dictionary exception occurs in the 
sanity checks. Below is the full function with the revised sanity check 
for positions that compares the input list with the two valid lists of 
board positions.



def generate_set(color, positions):

if positions not in [VARS['COORDINATES'][VARS['BOARD_BOTTOM']],
 VARS['COORDINATES'][VARS['BOARD_TOP']]]:
raise Exception("List for positions contains no valid 
coordinates, "

"got {} instead.".format(positions))

# generate objects according to color and position
for position in positions:
rank, file = position
if rank in VARS['RANK_NOBILITY']:
if file in VARS['FILE_ROOK']:
yield Rook(color, position)
elif file in VARS['FILE_BISHOP']:
yield Bishop(color, position)
elif file in VARS['FILE_KNIGHT']:
yield Knight(color, position)
elif file is VARS['FILE_QUEEN']:
yield Queen(color, position)
elif file is VARS['FILE_KING']:
yield King(color, position)
else:
yield Pawn(color, position)



I meant, what goes wrong if the number of positions input is other than
16? Without these "sanity" checks, your functions might be reusable in,
say, a checkers game.


Chess has 16 pieces (six types) on each side that are set up on the 
board in a particular order. Checkers has 12 pieces (one type) on each 
side that are set up on alternating squares in no particular order. 
Since I'm writing a chess engine because it has endless supply of 
programming changes, I have no desire to write reusable code for two 
similar but different games at the same time.


Thanks,

Chris R.

--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-19 Thread Michael Selik
On Mon, Apr 18, 2016 at 1:05 AM Christopher Reimer <
christopher_rei...@icloud.com> wrote:

> On 4/17/2016 3:18 PM, Michael Selik wrote:
>
> > I'd rather turn the question around: how much sanity checking is
> > necessary or useful? You'll find the answer is "surprisingly little"
> > compared to your experience in Java.
>
> I'm looking for a pythonic approach to sanity checking. From what I read
> elsewhere, sanity checking belongs in the unit tests and/or library
> classes designed for other people to use. I haven't seen many examples
> of sanity checks that is common in Java.
>
> > For example, you don't need to
> > explicitly check whether the color is present in your dictionary,
> > because it'll give you a KeyError if you look up a bad key.
>
> Without the sanity check against the constant dictionary, the color
> variable could be anything (it should be a string value). Looking at the
> code again, I should relocate the sanity checks in the Piece base class.
>

Why relocate rather than remove? What message would you provide that's
better than ``KeyError: 42`` with a traceback that shows exactly which
dictionary is being used and how?

> Why does the len of positions need to be 16?
>
> The positions variable is list of coordinates for 16 chess pieces (eight
> pawns, two rooks, two knights, two bishops, a king and a queen) for each
> color, locating the pieces on either the bottom quarter (i.e., [(1,1),
> ..., (2,8)]) or the top quarter (i.e., [(7,1), ..., (8,8)]) of the board.
>

I meant, what goes wrong if the number of positions input is other than 16?
Without these "sanity" checks, your functions might be reusable in, say, a
checkers game.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-17 Thread Ethan Furman

On 04/17/2016 12:34 PM, Christopher Reimer wrote:


How much sanity checking is too much in Python?


What happens if your extensive sanity checks turn up a bug?

In Python the usual answer is you raise an error:

raise ValueError('blahblah not a valid color')

What happens if you don't sanity check anything and the wrong color is 
passed in?


Python will raise an error for you:

Traceback
  ...
KeyError: 'blahblah' not found

---

I sanity check for three reasons:

1) raise a nicer error message

2) keep the point of failure close to the error

3) the consequences of bad data are Bad Bad Things (tm)

If none of those apply, I don't bother sanity checking.

--
~Ethan~

--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-17 Thread Christopher Reimer

On 4/17/2016 3:18 PM, Michael Selik wrote:


I'd rather turn the question around: how much sanity checking is
necessary or useful? You'll find the answer is "surprisingly little"
compared to your experience in Java.


I'm looking for a pythonic approach to sanity checking. From what I read 
elsewhere, sanity checking belongs in the unit tests and/or library 
classes designed for other people to use. I haven't seen many examples 
of sanity checks that is common in Java.



For example, you don't need to
explicitly check whether the color is present in your dictionary,
because it'll give you a KeyError if you look up a bad key.


Without the sanity check against the constant dictionary, the color 
variable could be anything (it should be a string value). Looking at the 
code again, I should relocate the sanity checks in the Piece base class.



Why does the len of positions need to be 16?


The positions variable is list of coordinates for 16 chess pieces (eight 
pawns, two rooks, two knights, two bishops, a king and a queen) for each 
color, locating the pieces on either the bottom quarter (i.e., [(1,1), 
..., (2,8)]) or the top quarter (i.e., [(7,1), ..., (8,8)]) of the board.


Thanks,

Chris R.
--
https://mail.python.org/mailman/listinfo/python-list


Re: How much sanity checking is required for function inputs?

2016-04-17 Thread Michael Selik
On Sun, Apr 17, 2016, 4:35 PM Christopher Reimer <
christopher_rei...@icloud.com> wrote:

> Greetings,
>
> I'm currently building a chess engine to learn the finer details of
> Python. When I learned all flavors of Java in community college a decade
> ago, we had to sanity check the hell out of the input values for every
> function and wrote a lot of redundant code in addition to the
> getters/setters code.
>
> Here's the input sanity checking I got for a generator function to
> return a set of chess pieces for a specified color and position.
>
>
> def generate_set(color, positions):
>
>  if color not in [VARS['COLOR_BLACK'], VARS['COLOR_WHITE']]:
>  raise Exception("Require \'{}\' or \'{}\' for input value, got
> \'{}\' instead.".format(VARS['COLOR_BLACK'], VARS['COLOR_WHITE'], color))
>
>  if len(positions) != 16:
>  raise Exception("Require 16 positions for input value, got {}
> instead.".format(len(positions)))
>
>
> The two sanity checks are fairly straight forward. Color input has to
> match the color constant strings. Positions input has to have 16 items.
>
> I *could* sanity check the positions input to determine if it had a list
> of 16 valid coordinates. The reason I don't is because the code that
> calls this function builds the coordinates from constants with valid
> coordinates. However, if I was doing this in my Java classes, one of my
> instructors rap me on the knuckles for not sanity checking to nth degree.
>
> How much sanity checking is too much in Python?
>

I'd rather turn the question around: how much sanity checking is necessary
or useful? You'll find the answer is "surprisingly little" compared to your
experience in Java. For example, you don't need to explicitly check whether
the color is present in your dictionary, because it'll give you a KeyError
if you look up a bad key.

Why does the len of positions need to be 16?

>
-- 
https://mail.python.org/mailman/listinfo/python-list


How much sanity checking is required for function inputs?

2016-04-17 Thread Christopher Reimer

Greetings,

I'm currently building a chess engine to learn the finer details of 
Python. When I learned all flavors of Java in community college a decade 
ago, we had to sanity check the hell out of the input values for every 
function and wrote a lot of redundant code in addition to the 
getters/setters code.


Here's the input sanity checking I got for a generator function to 
return a set of chess pieces for a specified color and position.



def generate_set(color, positions):

if color not in [VARS['COLOR_BLACK'], VARS['COLOR_WHITE']]:
raise Exception("Require \'{}\' or \'{}\' for input value, got 
\'{}\' instead.".format(VARS['COLOR_BLACK'], VARS['COLOR_WHITE'], color))


if len(positions) != 16:
raise Exception("Require 16 positions for input value, got {} 
instead.".format(len(positions)))



The two sanity checks are fairly straight forward. Color input has to 
match the color constant strings. Positions input has to have 16 items.


I *could* sanity check the positions input to determine if it had a list 
of 16 valid coordinates. The reason I don't is because the code that 
calls this function builds the coordinates from constants with valid 
coordinates. However, if I was doing this in my Java classes, one of my 
instructors rap me on the knuckles for not sanity checking to nth degree.


How much sanity checking is too much in Python?

Thank you,

Chris R


--
https://mail.python.org/mailman/listinfo/python-list