Re: Default Value

2013-06-21 Thread Chris Angelico
On Fri, Jun 21, 2013 at 1:16 PM, Rick Johnson
 wrote:
> On Thursday, June 20, 2013 7:57:28 PM UTC-5, Steven D'Aprano wrote:
>> Python functions are
>> created *once*, when defined. The cost of building the
>> function -- compiling the source code to byte code,
>> assembling the pieces into a function object, binding it
>> to a name -- happens once and once only, not every time
>> you call the function. So it is reasonable to expect that
>> since the function is defined once, so are any default
>> arguments.
>>
>
> Here you go again with this diversionary tactics! Of course
> the function is only compiled once! Anything else would be
> ludicrous. PAY ATTENTION! I'm not arguing that the damn
> function should be compiled each time it's called, no, i am
> arguing that each call to a subroutine should be a UNIQUE
> TRANSACTION. That means that no state can be carried from
> one transaction to another.

Why should that be? Why is a subroutine not allowed to retain any state?

You're free to write code in a purely functional style if you like -
all objects must be immutable, all functions must have no side effects
and simply return a value. That's not the only way to code, and it is
*definitely* not a rule to be codified into Python. One of Python's
strengths is that it permits many styles of programming, without
shoehorning every programmer and every task into one model.

Of course, RickPy 4000 is welcome to enforce all these sorts of inane
rules if it likes. I shan't be using it if it does.

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


Simple I/O problem can't get solved

2013-06-21 Thread nickgan . sps
Greetings to everybody,

I have recently started to solve my first Python problems but I came across to 
this:
Write a version of a palindrome recogniser that accepts a file name from the 
user, reads each line, and prints the line to the screen if it is a 
palindrome.(by http://www.ling.gu.se/~lager/python_exercises.html)

I think I coded it correctly but still I get no output. I do not have any 
errors I just do not get any output.

This is the code:

***
import is_palindrome

filename = raw_input('Enter a file: ') # A text file
f = open(filename)
while True:
line = f.readline()
if len(line) == 0:
break
elif is_palindrome.is_palindrome(line): 
print line,
f.close()
***

I have coded the is_palindrome module before and it works very well.
Here is this module's code:

***
def reverse(text):
return text[::-1]

def replace_all(text, dic):
for i, j in dic.iteritems():
text = text.replace(i, j)
return text

def is_palindrome(text):
return text == reverse(text)

points = {'.':'', ',':'', '!':'', ';':'', '?':'', '/':'', '\\':''}

something = raw_input('Enter text: ').lower().replace(' ', '')
replace = replace_all(something, points)
if is_palindrome(replace):
print 'Yes, it is a palindrome:', reverse(replace)
else:
print 'No, it is not a palindrome:', reverse(replace)
***

What should I do to output only the palindrome lines from the text file?
-- 
http://mail.python.org/mailman/listinfo/python-list


how can I check if group member exist ?

2013-06-21 Thread Hans
Hi,

I'm doing a regular expression matching, let's say 
"a=re.search(re_str,match_str)", if matching, I don't know how many str/item 
will be extracted from re_str, maybe a.group(1), a.group(2) exist but 
a.group(3) does not. 

Can I somehow check it? something like:
if exist(a.group(1)): print a.group(1)
if exist(a.group(2)): print a.group(2)
if exist(a.group(3)): print a.group(3)


I don't want to be hit by "Indexerror":
>>>print a.group(3)
Traceback (most recent call last):
  File "", line 1, in 
IndexError: no such group
>>> 

thanks!!!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Simple I/O problem can't get solved

2013-06-21 Thread Peter Otten
nickgan@windowslive.com wrote:

> I have recently started to solve my first Python problems but I came
> across to this:
> Write a version of a palindrome recogniser that accepts a file name from
> the user, reads each line, and prints the line to the screen if it is a
> palindrome.(by http://www.ling.gu.se/~lager/python_exercises.html)
> 
> I think I coded it correctly but still I get no output. I do not have any
> errors I just do not get any output.
> 
> This is the code:

> import is_palindrome
> 
> filename = raw_input('Enter a file: ') # A text file
> f = open(filename)
> while True:
> line = f.readline()

The line includes the trailing newline character which breaks the symmetry:

>>> "abba" == "abba"[::-1]
True
>>> "abba\n" == "abba\n"[::-1]
False

Use

word = line.strip()

to remove all leading and trailing whitespace.

> if len(line) == 0:
> break
> elif is_palindrome.is_palindrome(line): 
> print line,
> f.close()

Note that python allows you to iterate over the lines of a file with

for line in f:
...

Combining these modifications:

for line in f:
word = line.strip()
if is_palindrome.is_palindrome(word):
print word

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


Re: Simple I/O problem can't get solved

2013-06-21 Thread Jussi Piitulainen
nickgan@windowslive.com writes:

> I think I coded it correctly but still I get no output. I do not
> have any errors I just do not get any output.
> 
> This is the code:
> 
> ***
> import is_palindrome
> 
> filename = raw_input('Enter a file: ') # A text file
> f = open(filename)
> while True:
>   line = f.readline()
>   if len(line) == 0:
>   break
>   elif is_palindrome.is_palindrome(line): 
>   print line,
> f.close()

There's a newline at the end of each input line. Strip that. (It might
be another sequence that means end-of-line in your system. It can
still be stripped as trailing whitespace. Strings have a method for
stripping trailing whitespace.)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Don't feed the troll...

2013-06-21 Thread Antoon Pardon
Op 21-06-13 04:40, Ian Kelly schreef:

> On Thu, Jun 20, 2013 at 3:41 AM, Antoon Pardon
>  wrote:
>> There are two problems with your reasoning. The first is that you
>> are equivocating on "expect". "Expect" can mean you will be surprised
>> if it doesn't happen but it can also mean you will feel indignant or
>> disappointed or something similar when it doesn't happen.
>
> Perhaps I am, but it doesn't change my argument in any way.  When a
> troll shows up I am not happy about it, but I am not disappointed
> either, because Trolls Happen.  I am disappointed when members of the
> community act in ways that are detrimental to the community.  Better?

But that last one doesn't ring true. Enabling a troll is also acting
in a way that is detrimental to the community. But I haven't seen
you express disappointment in that.

Those that expressed their disappointment with the enabling behaviour
were more or less told they should deal with it. So tell me, why
should your disappointment merrit more consideration?

>
>> The second problem is that I find it a one sided view. If you want
>> a courteous, respectful, welcoming and enjoyable to participate in
>> list, shouldn't you also be careful in not encouraging trollish
>> behaviour? Being courteous to or cooperating with someone behaving
>> trollishly, is IMO enabling that kind of behaviour and so those
>> doing so, seem to already throw those priciples out the window because
>> they are cooperating with the troll who is making this list less
>> courteous, respectful, welcoming and enjoyable to participate in
>> for a significant number of people.
>
> You'll note that I haven't engaged Nikos at all in some time.  That's
> because I think he's a troll.  I think though that those who are
> continuing to help him do so because they do not think that he is a
> troll.  I am not going to try to thrust my own opinion of who is or is
> not a troll and who can or cannot be given help upon the list -- that
> is their opinion, they are entitled to it, and maybe they see
> something in the exchange that I don't. 

That doesn't change one bit of the fact they are enabling someone
who exhibits assholery behaviour. Who since he started here has
regularly changed his identity, yet these enablers keep suggesting
that those who are bothered by him should just killfile him. If
they were serious with that suggestion they at least could have
told Nikos they were only going to reply to one specific identity.


> That is different in my eyes from somebody who does identify Nikos as
> a troll and then goes on to egg him on anyway, whether it be courteous
> or belligerent.


In my eyes that is a difference that only counts at the start of
an exchange. Helping others allthough a fine goal by itself is not
something that can be used to justify any means. If you learn that
the person you are helping is showing assholery behaviour and how
you are helping, sure looks like encouraging that assholery behaviour.
When you decide to mostly ignore that, you are showing no concern
for the other contributers on the list and are acting in a way
that is detrimental to the community.

If you want the python list to be a hospitable place, you have
to be attentive for signals from other contributors that the
level of hospitability is decreasing for them. If you ignore
them or brush them off you then risk loosing them as cooperators
to that goal. So if later you find the level of hospitability
is decreasing for you, you are more likely to get ignored or
brushed off too.


-- 

Antoon Pardon

 


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


Re: how can I check if group member exist ?

2013-06-21 Thread Peter Otten
Hans wrote:

> Hi,
> 
> I'm doing a regular expression matching, let's say
> "a=re.search(re_str,match_str)", if matching, I don't know how many
> str/item will be extracted from re_str, maybe a.group(1), a.group(2) exist
> but a.group(3) does not.
> 
> Can I somehow check it? something like:
> if exist(a.group(1)): print a.group(1)
> if exist(a.group(2)): print a.group(2)
> if exist(a.group(3)): print a.group(3)
> 
> 
> I don't want to be hit by "Indexerror":
print a.group(3)
> Traceback (most recent call last):
>   File "", line 1, in 
> IndexError: no such group
 
> 
> thanks!!!

You could catch the exception

for index in itertools.count(1):
try:
print a.group(index)
except IndexError:
break

but in this case there's the groups() method:

for g in a.groups():
print g


The interactive interpreter is a good tool to find candidates for a solution 
yourself:

>>> a = re.compile("(.)(.)(.)").search("alpha")
>>> dir(a)
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', 
'__format__', '__getattribute__', '__hash__', '__init__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', 'end', 'endpos', 'expand', 'group', 
'groupdict', 'groups', 'lastgroup', 'lastindex', 'pos', 're', 'regs', 
'span', 'start', 'string']

>From the above names lastindex looks promising, too. Can you find out how 
the output of

for i in range(a.lastindex):
print a.group(i+1)

differs from that of looping over groups()?

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


Re: Simple I/O problem can't get solved

2013-06-21 Thread nickgan . sps
Τη Παρασκευή, 21 Ιουνίου 2013 12:15:59 μ.μ. UTC+3, ο χρήστης Peter Otten έγραψε:
> nickgan@windowslive.com wrote:
> 
> 
> 
> > I have recently started to solve my first Python problems but I came
> 
> > across to this:
> 
> > Write a version of a palindrome recogniser that accepts a file name from
> 
> > the user, reads each line, and prints the line to the screen if it is a
> 
> > palindrome.(by http://www.ling.gu.se/~lager/python_exercises.html)
> 
> > 
> 
> > I think I coded it correctly but still I get no output. I do not have any
> 
> > errors I just do not get any output.
> 
> > 
> 
> > This is the code:
> 
> 
> 
> > import is_palindrome
> 
> > 
> 
> > filename = raw_input('Enter a file: ') # A text file
> 
> > f = open(filename)
> 
> > while True:
> 
> > line = f.readline()
> 
> 
> 
> The line includes the trailing newline character which breaks the symmetry:
> 
> 
> 
> >>> "abba" == "abba"[::-1]
> 
> True
> 
> >>> "abba\n" == "abba\n"[::-1]
> 
> False
> 
> 
> 
> Use
> 
> 
> 
> word = line.strip()
> 
> 
> 
> to remove all leading and trailing whitespace.
> 
> 
> 
> > if len(line) == 0:
> 
> > break
> 
> > elif is_palindrome.is_palindrome(line): 
> 
> > print line,
> 
> > f.close()
> 
> 
> 
> Note that python allows you to iterate over the lines of a file with
> 
> 
> 
> for line in f:
> 
> ...
> 
> 
> 
> Combining these modifications:
> 
> 
> 
> for line in f:
> 
> word = line.strip()
> 
> if is_palindrome.is_palindrome(word):
> 
> print word

Thank you a lot it worked!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: how can I check if group member exist ?

2013-06-21 Thread Ben Finney
Hans  writes:

> I'm doing a regular expression matching, let's say
> "a=re.search(re_str,match_str)", if matching, I don't know how many
> str/item will be extracted from re_str

Can you show an example of the pattern, and several examples of text you
want to match? This will help to understand your issue.

Also, your terminology is using some confusing names. Try:

match = re.search(pattern, text)

That will use names which make it easier to think about the code.

-- 
 \ “Ours is a world where people don't know what they want and are |
  `\   willing to go through hell to get it.” —Donald Robert Perry |
_o__)  Marquis |
Ben Finney

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


New line conversion with Popen attached to a pty

2013-06-21 Thread Jonathan Harden
Hi,

We have a class which executes external processes in a controlled environment 
and does "things" specified by the client program with each line of output. To 
do this we have been attaching stdout from the subprocess.Popen to a pseudo 
terminal (pty) made with pty.openempty and opened with os.fdopen. I noticed 
that we kept getting a bunch of extra new line characters. 

This is all using python 2.6.4 in a centos6 environment.

After some investigation I realised we needed to use universal_newline support 
so I enabled it for the Popen and specified the mode in the fdopen to be rU. 
Things still seemed to be coming out wrong so I wrote up a test program boiling 
it down to the simplest cases (which is at the end of this message). The output 
I was testing was this:

Fake\r\nData\r\n
as seen through hexdump -C:

> hexdump -C output.txt 
  46 61 6b 65 0d 0a 44 61  74 61 0d 0a  |Fake..Data..|
000c

Now if I do a simple subprocess.Popen and set the stdout to subprocess.PIPE, 
then do p.stdout.read() I get the correct output of

Fake\nData\n

When do the Popen attached to a pty I end up with

Fake\n\nData\n\n

Does anyone know why the newline conversion would be incorrect, and what I 
could do to fix it? In fact if anyone even has any pointers to where this might 
be going wrong I'd be very helpful, I've done a lot of hours of fiddling with 
this and googling to no avail.

Thanks,

Jonathan

#!/usr/bin/env python2.6.4
import os
import pty
import subprocess
import select
import fcntl

class TestRead(object):

def __init__(self):
super(TestRead, self).__init__()
self.outputPipe()
self.outputPty()

def outputPipe(self):
p1 = subprocess.Popen(
("/bin/cat", "output.txt"),
stdout=subprocess.PIPE,
universal_newlines=True
)
print "1: %r" % p1.stdout.read()

def outputPty(self):
outMaster, outSlave = pty.openpty()
fcntl.fcntl(outMaster, fcntl.F_SETFL, os.O_NONBLOCK)

p2 = subprocess.Popen(
("/bin/cat", "output.txt"),
stdout=outSlave,
universal_newlines=True
)

with os.fdopen(outMaster, 'rU') as pty_stdout:
while True:
try:
rfds, _, _ = select.select([pty_stdout], [], [], 0.1)
break
except select.error:
continue

for fd in rfds:
buf = pty_stdout.read()
print "2: %r" % buf

if __name__ == "__main__":
t = TestRead()
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: Dealing with ' (suds)

2013-06-21 Thread Ombongi Moraa Fe
Hello,

I'm working with suds to send send messages to smsc. I've notices the
messages with ' are really not processed on my side (which could mean
an error occurs somewhere - most probably in my php script). SMSC has also
asked that I 'take care of the '' as it's the reason my subscribers
may not be receiving the responses.

How can i 'take care of ' ' so it doesn't give me problems in future?

Faith
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Lefavor, Matthew (GSFC-582.0)[MICROTEL LLC]
Or, in many MANY cases, the choice was the right one, but isn't
obvious to everyone.

I think it's worth pointing out that changing function defaults to
late-binding would merely change the nature of the gotcha, not eliminate it.

words = ("one", "two", "red", "blue", "fish")

def join_strings(strings=words):
   return ' '.join('%s %s' % (s, strings[-1]) for s in strings[:-1])

# Later:
words = open("gettysburg_address.txt", "r").read().split()
# Oops, the default argument of join_strings just changed.

+1. This is what convinces me that keeping references to keyword arguments is 
actually the right thing to do.

Perhaps I'm biased because I'm used to the mutable-argument behavior by now, 
but the gotcha described above seems to be much harder to track down and 
understand than any bugs caused by mutable arguments. With mutable arguments, 
at least you know the cause is in the function definition. If you initialized 
variables each time, you'd have to track the problem down across the entire 
namespace.

I, for one, would much rather follow the rule "don't use mutable arguments in 
function definitions" than "don't ever re-use the name of your variables."

ML
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: New line conversion with Popen attached to a pty

2013-06-21 Thread jfharden
On Thursday, 20 June 2013 23:04:39 UTC+1, Peter Otten  wrote:

> (2) Fiddle with terminal options, e. g.
> 
> attrs = termios.tcgetattr(outSlave)
> attrs[1]  =  attrs[1] & (~termios.ONLCR) | termios.ONLRET
> termios.tcsetattr(outSlave, termios.TCSANOW, attrs)
> 
> p = subprocess.Popen(
> ("/bin/cat", "output.txt"),
> stdout=outSlave,
> )
>
> Disclaimer: I found this by try-and-error, so it may not be the "proper" 
> way.

Thank you! That is absolutely perfect. I had read about pty options but didn't 
think to read about tty options. If we ever meet in real life remind me to buy 
you a beverage of your choosing.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: New line conversion with Popen attached to a pty

2013-06-21 Thread jfharden
On Thursday, 20 June 2013 11:20:20 UTC+1, Jonathan Harden  wrote:
>
...SNIP
>

Sorry about the second post, it took a very long time to show up, long enough I 
thought it had been lost.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A Beginner's Doubt

2013-06-21 Thread augustofec
Hello again!

Wow, I didn't  expect so many responses in a so short amount of time! You guys 
are amazing! All were very helpful, and after a quick read now I guess I can at 
least figure out a more focused path to achieve my goal.

I'm already checking the Tkinter tutorial, and as soon as I get a result I'll 
post it here to give a response :).

Yes, I forgot to mention some things: I have absolutely no knowledge about 
programming due to the fact that I'm a Visual Arts student, being my professor, 
accordingly, a Photography teacher with absolutely no idea of this field! He 
has, however, these kinds of 'multi-platform' projects, and since I was the 
fortunate student next to him when he came up with the idea, I got dragged into 
it.

The reason why I choose Python is that, once ago, I had some curiosity about 3D 
Modelling and game programming, which made me come across some texts praisng 
Python as an easy to learn and powerful language (despite the own concepts of 
an "easy" and "powerful" language being something quite vague for me :p).

That said, I would also like to apology for eventual typos and grammar errors 
since english is not my first language. By "side menu" I just imagined a menu 
in the left side of the screen, pretty much like the one in the Google groups 
page. 

And by copying the image from the menu to the canvas, when dragging it, I 
imagined a way to just place it, like a stamp, on the blank area where the user 
can in fact interact with it trought the editing tools (resize, rotate, color 
etc..).

Well, once again I thank you all and by now I'm gonna study!

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


Re: New line conversion with Popen attached to a pty

2013-06-21 Thread Dave Angel

On 06/20/2013 06:20 AM, Jonathan Harden wrote:

Hi,

We have a class which executes external processes in a controlled environment and does 
"things" specified by the client program with each line of output. To do this 
we have been attaching stdout from the subprocess.Popen to a pseudo terminal (pty) made 
with pty.openempty and opened with os.fdopen. I noticed that we kept getting a bunch of 
extra new line characters.



Duplicate thread, delayed by the vagaries of email and gateways.  In 
that thread, the problem has been happily resolved.


Any responses, please keep them on the other thread with the same title.


--
DaveA
--
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 2:10:49 AM UTC-5, Chris Angelico wrote:
> Why should that be? Why is a subroutine not allowed to
> retain any state?

I refuse to repeat myself for lazy readers!

> You're free to write code in a purely functional style if
> you like

I don't want to write code in a purely functional style, i
find that style too restricting.

> all objects must be immutable,

That would suck!
 
> all functions must have no side effects and simply return
> a value.

No thanks!
 
> One of Python's strengths is that it permits many styles
> of programming, without shoehorning every programmer and
> every task into one model.

Yes, and i consider that aspect of Python a virtue. But this
"persistence of mutable arguments" is not a virtue, it's an
abomination!

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


Re: Problem with the "for" loop syntax

2013-06-21 Thread Neil Cerutti
On 2013-06-20, Cameron Simpson  wrote:
> On 20Jun2013 13:55, Neil Cerutti  wrote:
>| On 2013-06-20, Joshua Landau  wrote:
>| > On 20 June 2013 04:11, Cameron Simpson  wrote:
>| >> Also, opening-and-not-closing a set of brackets is almost the
>| >> only way in Python to make this kind of error (syntax at one
>| >> line, actual mistake far before).
>| >>
>| >> See if your editor has a show-the-matching-bracket mode.
>| >> If you suspect you failed to close a bracket, one approach is
>| >> to go _below_ the syntax error (or right on it) and type a
>| >> closing bracket. Then see where the editor thinks the opening
>| >> one is.
>| >
>| > Thanks for that, that's quite an ingenious technique.
>| 
>| The auto-indent feature of Vim catches this type of syntax error,
>| and I imagine other good autoindent support will do the same.
>
> Interesting. I use autoindent but grew up with it for prose. I
> hadn't realised vim's support inderstaood python indentation.
> I'll have to pay more attention...

A standard Vim install autoindents Python tolerably well if
you've set filetype=python. If you've got a baked-in Python
interpreter you can get even more bells and whistles. The
standard executable installs I could find don't support Python 3,
so I haven't seen all the great stuff I'm missing.

-- 
Neil Cerutti
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Rick Johnson
On Thursday, June 20, 2013 5:28:06 PM UTC-5, Lefavor, Matthew 
(GSFC-582.0)[MICROTEL LLC] wrote:
> 
> [snip example showing dummy coder doing something dumb]
>
> +1. This is what convinces me that keeping references to
> keyword arguments is actually the right thing to do.
> 
> Perhaps I'm biased because I'm used to the mutable-
> argument behavior by now, but the gotcha described above
> seems to be much harder to track down and understand than
> any bugs caused by mutable arguments. With mutable
> arguments, at least you know the cause is in the function
> definition. If you initialized variables each time, you'd
> have to track the problem down across the entire
> namespace.

That's because you and many other folks, who keep supporting
this BS idea, have become SO accustomed to writing code in a
sloppy manner, that you need this flaw to save yourself,
FROM YOURSELF!

 " Hello, allow myself to introduce myself"

Apparently you don't understand the value of writing rock
solid code. Instead of passing your mutables in as
arguments, all you have to do is reference them properly in
the BODY of the subroutine and everything will work just
fine. If you fear global level variables then write up a
simple Object definition to encapsulate the mutable and make
it callable.


 Thought Exercise:


Let's imagine for a second if Python allowed mutable keys in
a dictionary, would you be surprised if you used a mutable
for a key, then you mutated the mutable key, then you could
not access the value from the original key? 

 ## Imaginary code ##
 py> lst = [3]
 py> d = {1:2, lst:4}
 py> lst.append(10)
 py> d[lst]
 opps, KeyError!

Would you REALLY be so surprised? I would not. But more
importantly, does Python need to protect you from being such
an idiot? I don't think so!

Any "intelligent" programmer would NEVER use mutable keys
for a hash table -- unless he had a very good reason and was
willing to take the risks -- EVEN IF the language allowed
such foolishness!

But you people will sit here all day arguing that "early
binding" is warranted on the grounds that people need to be
protected from doing stupid things -- like passing mutables
as arguments to subroutines. This is a weak argument. Tell
me you have something better, tell me the fate of this 
language does not revolve around benevolent idiocy!

If you really want to save the poor idiot from writing code
that could fail, a leader ruled by benevolence, but who has
a modicum of intelligence remaining, would simply throw up a
warning.

  Warning: 
Argument "lst" to function "poopoo" has been mutated, 
which could cause a subtle bug on successive calls. 
YOU HAVE BEEN WARNED!

What you never, EVER, want to do is to use idiots for an
excuse to create some esoteric abomination of persistent
mutables between successive calls of subroutines. 

> I, for one, would much rather follow the rule "don't use
> mutable arguments in function definitions"

Yes, that's the exact point i'm making! A little self
discipline can go a long way

> than "don't ever re-use the name of your variables."

Well, we're not even talking about that, but i understand
the value of your statement. Although, i think your
comparing Apples and Oranges.

PS: First you support the opposition. now you go an do a
180? You're confusing the hell out of me Matthew! @_@
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding all instances of a string in an XML file

2013-06-21 Thread Jason Friedman
Thank you Peter and Dieter, will give those thoughts a try and report back.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Steven D'Aprano
On Thu, 20 Jun 2013 11:05:32 -0700, Rick Johnson wrote:

> Python functions are objects that take arguments, of which (the
> arguments) are then converted to attributes of the function object.
> Ah-Ha! Urm, but wait! We already have a method to define Objects. Heck,
> I can even create my own callable objects if i want!
> 
> Observe:
>   py> class FuncAdd(object):
>   ... def __init__(self, ivalue):
>   ... self.ivalue = ivalue

Notice how you are storing state here? I thought you said, and I quote:

"When the subroutine is completed, ALL INPUTS and local variables are 
expected to be destroyed. If the programmer wants a return value, he need 
simply ask. Data persistence is NOT a function of subroutines!" 
[emphasis added] 

And yet here you are defining persistent input ("ivalue") to the callable 
subroutine, which is stored as external state and not destroyed at the 
end of the subroutine call:

>   ... def __call__(self, numeric):
>   ... return self.ivalue + numeric 
>   ... 

All you have done here is define a subroutine with state, precisely the 
thing that you say subroutines must never have. What you haven't done is 
define a function which takes a default value that can be overridden when 
called. Your argument is invalid.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Don't feed the troll...

2013-06-21 Thread Ian Kelly
On Fri, Jun 21, 2013 at 3:18 AM, Antoon Pardon
 wrote:
> Op 21-06-13 04:40, Ian Kelly schreef:
>
>> On Thu, Jun 20, 2013 at 3:41 AM, Antoon Pardon
>>  wrote:
>>> There are two problems with your reasoning. The first is that you
>>> are equivocating on "expect". "Expect" can mean you will be surprised
>>> if it doesn't happen but it can also mean you will feel indignant or
>>> disappointed or something similar when it doesn't happen.
>>
>> Perhaps I am, but it doesn't change my argument in any way.  When a
>> troll shows up I am not happy about it, but I am not disappointed
>> either, because Trolls Happen.  I am disappointed when members of the
>> community act in ways that are detrimental to the community.  Better?
>
> But that last one doesn't ring true. Enabling a troll is also acting
> in a way that is detrimental to the community. But I haven't seen
> you express disappointment in that.

I've already explained why that is.  First, it's less anguish to
kill-file one troll than several vitriolic regulars (and I realize
that he keeps changing his name, but fortunately I think he's only
used three different /addresses/ in the time that he's been posting).
Second, I don't want to bully anybody into not trying to help a user
where they want to and believe that they can.  It may be "enabling"
for the troll, but it's unhealthy for the list in general.

> Those that expressed their disappointment with the enabling behaviour
> were more or less told they should deal with it. So tell me, why
> should your disappointment merrit more consideration?

When did I ever say that it should?  I'm just putting my own opinions
on the subject out there.

> If you want the python list to be a hospitable place, you have
> to be attentive for signals from other contributors that the
> level of hospitability is decreasing for them. If you ignore
> them or brush them off you then risk loosing them as cooperators
> to that goal. So if later you find the level of hospitability
> is decreasing for you, you are more likely to get ignored or
> brushed off too.

The level of hospitality is already decreasing for me.  That's why I'm
speaking up.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Steven D'Aprano
On Thu, 20 Jun 2013 20:16:19 -0700, Rick Johnson wrote:

> On Thursday, June 20, 2013 7:57:28 PM UTC-5, Steven D'Aprano wrote:
>> On Thu, 20 Jun 2013 11:05:32 -0700, Rick Johnson wrote:

>> They [default argument values] have to be stored *somewhere*, and
>> Python chooses to store them as an attribute of the function object,
>> where they can be easily inspected, rather than by storing them inside
>> some undocumented and hidden location locked up in a binary blob.
> 
> I like how that last sentence implicitly argues against an argument i
> never made, whilst explicitly supporting your argument. 

You're overly defensive. I never said, or even suggested, that you argued 
the opposite. I simply state a fact: any language with default arguments 
must store the default argument somewhere. In a language with early 
binding of default arguments, the *value itself* must be stored. In a 
language with late binding, *the expression that generates that value* 
(sometimes called a "thunk") must be stored.

The consequence of this fact is that if you wish to argue that functions 
have no business storing state, then you're arguing that functions must 
not have default arguments.


[...]
>> Even if Python chose late binding instead of early binding for function
>> defaults, the default would *still* need to be stored somewhere.
> 
> No, if your passing in a symbol, then the object it points to must exist
> *somewhere*. OTOH if your passing in a literal, or an expression, then
> the subroutine will need to "store" the resulting object. Yes.

Passing in a symbol? I'm afraid I don't understand you. Do you mean a 
name? Something like:

def func(x=y):
...

A single name, like 'y' above, is an expression. In any case, while the 
name must exist at the time the function is defined, it does not need to 
exist when the function is called:

py> y = 23
py> def func(x=y):
... return x
...
py> del y
py> func()
23


>> The only difference is that with early binding, the default value is
>> calculated once, and the object stored, while with late binding the
>> default value is re-calculated over and over again, every time it is
>> needed, and a piece of code that calculates the default value is
>> stored.
> 
> And that is *ONLY* the case using the currently broken system.

No. You have failed to understand. ANY language that offers default 
values for function parameters must operate under the same limitation. 
The language must store either the default value itself, or some 
executable expression that generates that default value.

Even if your language doesn't offer default values, all this means is 
that the responsibility for doing this is moved away from the compiler to 
you. For instance, if your languages offers an "is_undefined" function, 
you can manually store the default value in a global variable and then 
retrieve it when needed:


# Store function state in a global variable.
default := [];

def func(x):
   if is_undefined(x):
 {
  x := default;
  }
   ...


That suffers the *exact same gotcha* as Python if the default value is 
mutable.

Or you can store the state in a callable class, what C++ calls a functor:

class MyClass:
# Store function state in a class member.
default := [];
def __call__(this, x):
if is_undefined(x):
  {
   x := this.default;
   }
...

This too suffers the *exact same gotcha* as Python if the default is 
mutable. Storing the function state as an instance member instead of a 
class member doesn't save you; the same applies.

There are only three ways to avoid the mutable default gotcha:

* Prohibit default arguments, and don't provide an is_undefined 
  test. All function arguments *must* be supplied explicitly by 
  the caller, like in Pascal.

* Use late-binding and re-calculate the default every time it is
  needed. This risks being expensive, and has its own share of 
  gotchas.

* If you can somehow determine which values are mutable and which 
  are not, you might allow default arguments only for immutable 
  values. Some restrictive languages can do this: Java, with it's
  strongly enforced rules for "private" and "protected" members,
  and compile-time checks, may be able to do something like this.
  And purely functional languages like Haskell simply avoid the
  issue by ensuring that *all* values are immutable. But for 
  Python, it is impossible.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 10:57:17 AM UTC-5, Steven D'Aprano wrote:
> On Thu, 20 Jun 2013 11:05:32 -0700, Rick Johnson wrote:
> >   py> class FuncAdd(object):
> >   ... def __init__(self, ivalue):
> >   ... self.ivalue = ivalue
> Notice how you are storing state here? I thought you said,
> and I quote: "When the subroutine is completed, ALL INPUTS
> and local variables are expected to be destroyed. If the
> programmer wants a return value, he need simply ask. Data
> persistence is NOT a function of subroutines!" 
> [emphasis added]
> 
> And yet here you are defining persistent input ("ivalue")
> to the callable subroutine, which is stored as external
> state and not destroyed at the end of the subroutine call:

Because Steven, my dear lad, what i created is NOT a
subroutine, no, it's an object that stores state and is
callable. Each call to the object is merely a request to
mutate and then return it's current state. A subroutine, at
least REAL subroutines (not the snake oil that Python is
selling) do not have state. 

Real subroutines merely:
 1. Optionally take inputs
 2. Execute a body of code (which could have side effects, 
but which is NOT persistent!)
 3. Optionally return output

That's it. If your problem requires state persistence, then
you need to move up to an Object definition. Use the correct
tool for the job dammit!

> >   ... def __call__(self, numeric):
> >   ... return self.ivalue + numeric 
> >   ... 
> All you have done here is define a subroutine with state,
> precisely the thing that you say subroutines must never
> have. 

It's Okay to carry state EXPLICITLY, it's NOT okay to carry
state IMPLICITLY. My implementation is correct, Python's is
not. 

Besides, encapsulated state is one of the fundamental
principles of OOP programming, along with interfaces; and
i've satisfied both! The mutable is protected from the world
by an object, and the object allows manipulation of the
mutable via an interface.

But unlike Python's limited implementation, my approach is
scalable. I can change the interface, i can add more
functionality, i can do anything i want.

 "I am the Lizard King, and i can do, well ANYTHING!"
 
However, with Python's limited approach, i'm just a slave to
the implementation. I'm forced to follow estoeric rules with
no chance of scalability.

  
  #   Moral of the Day   #
  
  # You should only use SUBROUTINES for executing#
  # subprograms requiring stateless transactions.#
  # Alternativly, subprograms requiring persistant state #
  # transactions should wield the power of a custom  #
  # object defintion -- or you can use the   #
  # global+subroutine method if encapsulation is not #
  # warrented.   #
  

But in any case, following this advice will ensure less bugs
and more maintainable code than Python's current
implementation of lunacy.

> What you haven't done is define a function which takes a
> default value that can be overridden when called. 

Oh, you mean like this?

  py> class Func(object):
  ... def __call__(self, arg=0):
  ... print(arg)
  ... 
  py> f = Func()
  py> f("pwned")
  pwned

> Your argument is invalid.

My argument is not invalid, i just figured i did not need
wipe your bum for you, "Homer".  ~(_8^(I)

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


Re: Default Value

2013-06-21 Thread Rotwang

On 21/06/2013 18:01, Rick Johnson wrote:


[stuff]


It isn't clear to me from your posts what exactly you're proposing as an 
alternative to the way Python's default argument binding works. In your 
version of Python, what exactly would happen when I passed a mutable 
argument as a default value in a def statement? E.g. this:


>>> a = [1, 2, 3]
>>> a.append(a)
>>> b = object()
>>> def f(x = [None, b, [a, [4]]]):
... pass # do something

What would you like to see the interpreter do in this case?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 12:47:56 PM UTC-5, Rotwang wrote:
> It isn't clear to me from your posts what exactly you're
> proposing as an alternative to the way Python's default
> argument binding works. In your version of Python, what
> exactly would happen when I passed a mutable argument as a
> default value in a def statement? E.g. this:
>
>  >>> a = [1, 2, 3]
>  >>> a.append(a)
>  >>> b = object()
>  >>> def f(x = [None, b, [a, [4]]]):
> ... pass # do something
>
> What would you like to see the interpreter do in this case?

Ignoring that this is a completely contrived example that has
no use in the real world, here are one of three methods by
which i can handle this:


 The Benevolent Approach:

I could cast a "virtual net" over my poor lemmings before
they jump off the cliff by throwing an exception:

  Traceback (most recent screw-up last):
   Line BLAH in SCRIPT
def f(x = [None, b, [a, [4]]]):
  ArgumentError: No mutable default arguments allowed!


 The Apathetic Approach:

I could just assume that a programmer is responsible for the
code he writes. If he passes mutables into a function as
default arguments, and then mutates the mutable later, too
bad, he'll understand the value of writing solid code after
a few trips to exception Hell.


 The Malevolent Approach (disguised as beneva-loon-icy):

I could use early binding to confuse the hell out of him and
enjoy the laughs with all my ivory tower buddies as he falls
into fits of confusion and rage. Then enjoy again when he
reads the docs. Ahh, the gift that just keeps on giving!


 Conclusion:

As you can probably guess the malevolent approach has some
nice fringe benefits.

You know, out of all these post, not one of you guys has
presented a valid use-case that will give validity to the
existence of this PyWart -- at least not one that CANNOT be
reproduced by using my fine examples. All you can muster is
some weak argument about protecting the lemmings.

 Is anyone up the challenge?
 Does anyone here have any real chops?

PS: I won't be holding my breath.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Don't feed the troll...

2013-06-21 Thread rusi
On Friday, June 21, 2013 9:49:01 PM UTC+5:30, Ian wrote:
>
> The level of hospitality is already decreasing for me.  That's why I'm
> speaking up.

I believe that this can be a point of unanimity -- "The level of hospitality 
having gone down enough, I felt the need to speak up".

And with the immediate factor(s) for this in abeyance for the last couple of 
days, maybe we can shelve this and move on?

Just a suggestion and a request to all...
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Steven D'Aprano
On Fri, 21 Jun 2013 11:26:39 -0700, Rick Johnson wrote:

> You know, out of all these post, not one of you guys has presented a
> valid use-case that will give validity to the existence of this PyWart

LOL.

Okay, you're trolling. Time for another month in the kill-file.

*plonk*


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Chris Angelico
On Sat, Jun 22, 2013 at 4:26 AM, Rick Johnson
 wrote:
> I could cast a "virtual net" over my poor lemmings before
> they jump off the cliff by throwing an exception:
>
>   Traceback (most recent screw-up last):
>Line BLAH in SCRIPT
> def f(x = [None, b, [a, [4]]]):
>   ArgumentError: No mutable default arguments allowed!

So tell me, oh Great and Powerful Wizard of Rick, how is the
interpreter supposed to know which defaults are mutable? I mean, it's
obviously some intrinsic property of the object. Somehow one thing is
clearly immutable, another thing clearly isn't. Will there be a
PyObject_IsImmutable() API?

Oh! I know. Function argument defaults will now be restricted to
int/float/tuple. That would do it, right? Nobody would be bothered by
little restrictions like that, would they.

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


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 1:37:13 PM UTC-5, Steven D'Aprano wrote:
> Okay, you're trolling. Time for another month in the kill-file. 
> *plonk*

That's so typical of you. You start losing an argument, and
when you have no remaining counter arguments, you resort to
name calling. Why am i not surprised? You wanna see some
trolling?

Is this all you can conjure Steven "Sauron" D'Aprano? 

... A FEW MINDLESS ORCS?

I have defeated your orcs, and your cave trolls. I have
defeated you in my darkest hour in the keep. I have thrown
out that despot from the white city, i have even slain your
Nazgul. Heck, my little sister killed your witch king.

...AND STILL YOU THINK YOU CAN DEFEAT ME!

And now, here i stand, at the foot of the mountain of doom,
with the ring of *POWER* in my hand, and i shall cast it
into the fires from whence it came!

...WHO WILL STOP ME?

All you have remaining is your beloved "gollom van rossum"
and he has already defeated himself with his blind devotion
to this despicable ring. A ring that represents illogical
and inconsistent design philosophies. A philosophy that he
himself cannot defend.

Free my people from this plague of darkness, and cast light
on these atrocities so that the sun may bleach this language
and this community clean, and maybe we'll let you visit the
shire. 

...MAYBE!

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


Re: Default Value

2013-06-21 Thread Neil Cerutti
On 2013-06-21, Chris Angelico  wrote:
> On Sat, Jun 22, 2013 at 4:26 AM, Rick Johnson
> wrote:
>> I could cast a "virtual net" over my poor lemmings before
>> they jump off the cliff by throwing an exception:
>>
>>   Traceback (most recent screw-up last):
>>Line BLAH in SCRIPT
>> def f(x = [None, b, [a, [4]]]):
>>   ArgumentError: No mutable default arguments allowed!
>
> So tell me, oh Great and Powerful Wizard of Rick, how is the
> interpreter supposed to know which defaults are mutable? I
> mean, it's obviously some intrinsic property of the object.
> Somehow one thing is clearly immutable, another thing clearly
> isn't. Will there be a PyObject_IsImmutable() API?
>
> Oh! I know. Function argument defaults will now be restricted
> to int/float/tuple. That would do it, right? Nobody would be
> bothered by little restrictions like that, would they.

I've been around here long enough to have even participated in
one of these discussions before.

Rick, it's not a wart, It's a gotcha.

The reason it's a gotcha is this: In order to predict what will
happen correctly, you have to have mastered three separate Python
concepts.

1. How name-binding works.
2. How argument passing works, i.e., via name-binding.
3. When default arguments are evaluated.
4. The Python object model.

OK, you have to know four things. Curses! I'll come in again.

-- 
Neil Cerutti
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread MRAB

On 21/06/2013 19:26, Rick Johnson wrote:

On Friday, June 21, 2013 12:47:56 PM UTC-5, Rotwang wrote:

It isn't clear to me from your posts what exactly you're
proposing as an alternative to the way Python's default
argument binding works. In your version of Python, what
exactly would happen when I passed a mutable argument as a
default value in a def statement? E.g. this:

 >>> a = [1, 2, 3]
 >>> a.append(a)
 >>> b = object()
 >>> def f(x = [None, b, [a, [4]]]):
... pass # do something

What would you like to see the interpreter do in this case?


Ignoring that this is a completely contrived example that has
no use in the real world, here are one of three methods by
which i can handle this:


  The Benevolent Approach:

I could cast a "virtual net" over my poor lemmings before
they jump off the cliff by throwing an exception:

   Traceback (most recent screw-up last):
Line BLAH in SCRIPT
 def f(x = [None, b, [a, [4]]]):
   ArgumentError: No mutable default arguments allowed!


What about this:

def f(x=Foo()):
pass # do something

Should it raise an exception? Only if a Foo instance is mutable? How do
you know whether such an instance is mutable?



  The Apathetic Approach:

I could just assume that a programmer is responsible for the
code he writes. If he passes mutables into a function as
default arguments, and then mutates the mutable later, too
bad, he'll understand the value of writing solid code after
a few trips to exception Hell.


  The Malevolent Approach (disguised as beneva-loon-icy):

I could use early binding to confuse the hell out of him and
enjoy the laughs with all my ivory tower buddies as he falls
into fits of confusion and rage. Then enjoy again when he
reads the docs. Ahh, the gift that just keeps on giving!


How does the "Apathetic Approach" differ from the "Malevolent Approach"?



  Conclusion:

As you can probably guess the malevolent approach has some
nice fringe benefits.

You know, out of all these post, not one of you guys has
presented a valid use-case that will give validity to the
existence of this PyWart -- at least not one that CANNOT be
reproduced by using my fine examples. All you can muster is
some weak argument about protecting the lemmings.

  Is anyone up the challenge?
  Does anyone here have any real chops?

PS: I won't be holding my breath.


Speaking of which, on 11 January 2013, in the thread "PyWart: Import
resolution order", you were asked:

"""Got any demonstrable code for Python 4000 yet?"""

and you said:

"""I am working on it. Stay tuned. Rick is going to rock your little 
programming world /very/ soon."""


How soon is "/very/ soon" (clearly longer than 5 months), and how did
you fix this "PyWart"?

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


Re: Don't feed the troll...

2013-06-21 Thread Antoon Pardon

Op 19-06-13 23:13, ru...@yahoo.com schreef:

On 06/19/2013 04:57 AM, Antoon Pardon wrote:

Op 19-06-13 05:46, ru...@yahoo.com schreef:

On 06/18/2013 02:22 AM, Antoon Pardon wrote:



I don't remember making such a claim. What I do remember is
you among others claiming that the problem was not (so much)
the troll (Nikos) but the others. I only made the remark that
you can't claim the troll is not a problem if he provokes
behaviour you find problematic.
And your last conclusion is unsound. You forget to include the
fact that once a troll appeared, people reacting badly to the
troll is also to be expected. So with regards to this aspect
there is no difference between the troll and the responders,
both being expected and so no ground to put the preponderance
of blame on the responders.


No, "blame" implies assumption of a particular point of
view.  From a troll's viewpoint, newsgroup participants that
*don't* respond are to blame because they deprive the troll
of his fun.

Our viewpoint is that of newsgroup participants.  We assume
they have volition, else this whole thread is pointless.
Since they have a choice of how to respond, then if they
chose to respond in a way that produces an undesirable outcome,
then it is fair "blame" them.

The troll is outside the volition of the group and so his
appearance is effectively an act of nature.


This seems a rather artificial division. Especially because the
immediate cause that led to this discussion is Nikos. As the
situation is now I see very little reason to exclude Nikos
from the group. He has made a substantial number of contribution
and has received a substantial number of replies. So on what
grounds would you put Nikos outside the volition of this group?


I am not "drawing the line for them", I am drawing it for
me.  I think you see a non-existent conflict because you are
assume there is only one line.  I do not make that assumption.

If you think Nikos has crossed your line, then I acknowledge
your right not to help him.  I even acknowledge your right
to flame him and encourage others to do so.

My argument is that if you exercise your right (the flamage
part) the results on the newsgroup, when considered on a
best outcome for the most people basis, will be less good
than if you choose not to exercise your right.


Possibly. But I don't consider utiltarism such a good measuring
stick for these kind of situations. Too easy to neglect the
concerns of individuals or small groups.


The costs are different in magnitude.  Roughly:

1.People willing to read and possibly respond helpfully
   to Nikos.
2.People annoyed by Nikos who want him gone and don't want to
   see anything by him or in his threads.
(and if people find you convincing)
3.People annoyed by Nikos but willing to read his threads in
   order to send antagonistic posts.

If people ignore your call to spam Nikos with antagonistic
posts (and stop the considerable amount of such activity
already occurring) then the costs (difference compared to
a no-Nikos newsgroup) might be:

  Group 1: 0
  Group 2: 1 (killfile Nikos and kill or skip his new threads
   when encountered.)

If people continue to send both unhelpful and antagonistic
posts to Nikos:

  Group 1: 5 (can't killfile posters because they post in other
   non-Nikos threads.  Have to skip large volume of junk
   posts based on visual peek at contents or recognition
   of poster as a vigilante.)
  Group 2: 1 (killfile Nikos and kill or skip his new threads
   when encountered.)


I don't accept this as the way costs should be compared? Why are
you adding the costs of the flamers together? Each flamer is
an individual who should only be responsible for his own
contribution. As such it seems that the cost each flamer
is inducing is comparable to the cost Nikos is inducing.


As for those annoyed by Nikos but who
  >  "can't easily filter the valuable contributions
  >  in [a Nikos] thread from the nth repeated answer to the same
  >  question"
how is that different from any non-Nikos thread other than that
your proposed action that makes it harder?


It is different because Non-Nikos threads in general don't contain
so many repeated questions as Nikos threads.


Of course.  We all do that subconsciously every time we
read a newsgroup.  But that is not what we are discussing

We are discussing the effects of two different policies
of different interest groups on the newsgroup.  You advocate
a policy of not responding helpfully and responding aggressively
to those exhibiting "undesirable" behavior where "undesirable"
is defined by you or some vague group consensus.

I advocate a policy not responding aggressively at all and
responding helpfully or not at all based on a personal evaluation
of the "undesirable" behavior.

So the question to answer is: how do those different policies
affect the cost/benefits of the different groups and which one
leads to the greatest good for the most?


And I don't think that 

Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 2:18:27 PM UTC-5, Rick Johnson wrote:
> On Friday, June 21, 2013 1:37:13 PM UTC-5, Steven D'Aprano wrote:
> 
> > Okay, you're trolling.

Steven, you wouldn't know "trolling" even if you were an honorary salad tosser 
at a troll face-sitting contest.

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


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 2:20:22 PM UTC-5, Neil Cerutti wrote:
> Rick, it's not a wart, It's a gotcha. The reason it's a
> gotcha is this: In order to predict what will happen
> correctly, you have to have mastered three separate Python
> concepts.
>
> 1. How name-binding works.
> 2. How argument passing works, i.e., via name-binding.
> 3. When default arguments are evaluated.
> 4. The Python object model.

I understand all these concepts in a Python context quite
well, but understanding a PyWart is no validation for it's
continued existence. 

You probably understand the common cold quite well. If you
do you'll wash your hands before eating, and avoid exposure
to sick people.

 THAT'S CALLED A WORKAROUND!

But disease is not yet fully under human control, we are
forced to used the workaround. Whereas, languages are. So
designing a language poorly and then getting upset because
people don't praise your clunky work-around is ludicrous.

 Psst: THE PROBLEM IS SELF-INDUCED!

Mankind, the only creature dumb enough to self-induce his
own hardships -- somewhere a higher intelligence must be
laughing... or crying, who knows. *sigh*
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 2:25:49 PM UTC-5, MRAB wrote:
> On 21/06/2013 19:26, Rick Johnson wrote:
> > 
> >   The Apathetic Approach:
> > 
> > I could just assume that a programmer is responsible for the
> > code he writes. If he passes mutables into a function as
> > default arguments, and then mutates the mutable later, too
> > bad, he'll understand the value of writing solid code after
> > a few trips to exception Hell.
> > 
> >   The Malevolent Approach (disguised as beneva-loon-icy):
> > 
> > I could use early binding to confuse the hell out of him and
> > enjoy the laughs with all my ivory tower buddies as he falls
> > into fits of confusion and rage. Then enjoy again when he
> > reads the docs. Ahh, the gift that just keeps on giving!
>
> How does the "Apathetic Approach" differ from the
> "Malevolent Approach"?

In the apathetic approach i allow the programmer to be the
sole proprietor of his own misfortunes. He lives by the
sword, and thus, he can die by the sword.

Alternatively the malevolent approach injects misfortunes
for the programmer on the behalf of esoteric rules. In this
case he will live by sword, and he could die by the sword,
or he could be unexpectedly blown to pieces by a supersonic
Howitzer shell.

It's an Explicit death versus an Implicit death; and Explicit
should ALWAYS win! 

The only way to strike a reasonable balance between the
explicit death and implicit death is to throw up a warning:

 "INCOMING"

Which in Python would be the "MutableArgumentWarning".

*school-bell*
-- 
http://mail.python.org/mailman/listinfo/python-list


n00b question on spacing

2013-06-21 Thread Yves S. Garret
Hi, I have a question about breaking up really long lines of code in Python.

I have the following line of code:
log.msg("Item wrote to MongoDB database %s/%s" %(settings['MONGODB_DB'],
settings['MONGODB_COLLECTION']), level=log.DEBUG, spider=spider)

Given the fact that it goes off very far to the right on my screen is not
terribly
pleasing to my eyes (and can be rude for other developers).

I was thinking of splitting it up like so:
log.msg("Item wrote to MongoDB database %s/%s"
  %(settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
  level=log.DEBUG, spider=spider)

Is this ok?  Are there any rules in Python when it comes to breaking up
long lines of
code?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: n00b question on spacing

2013-06-21 Thread John Gordon
In  "Yves S. Garret" 
 writes:

> Hi, I have a question about breaking up really long lines of code in Python.

> I have the following line of code:
> log.msg("Item wrote to MongoDB database %s/%s" %(settings['MONGODB_DB'],
> settings['MONGODB_COLLECTION']), level=log.DEBUG, spider=spider)

> Given the fact that it goes off very far to the right on my screen is not
> terribly pleasing to my eyes (and can be rude for other developers).

> I was thinking of splitting it up like so:
> log.msg("Item wrote to MongoDB database %s/%s"
>   %(settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
>   level=log.DEBUG, spider=spider)

> Is this ok?  Are there any rules in Python when it comes to breaking up
> long lines of code?

There are guidelines in the PEP8 document:

http://www.python.org/dev/peps/pep-0008/

Check out the section entitled 'Code lay-out'.

-- 
John Gordon   A is for Amy, who fell down the stairs
gor...@panix.com  B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

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


Re: n00b question on spacing

2013-06-21 Thread Ray Cote
- Original Message -

> From: "Yves S. Garret" 
> To: python-list@python.org
> Sent: Friday, June 21, 2013 5:17:28 PM
> Subject: n00b question on spacing

> Hi, I have a question about breaking up really long lines of code in
> Python.

> I have the following line of code:
> log.msg("Item wrote to MongoDB database %s/%s"
> %(settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
> level=log.DEBUG, spider=spider)

> Given the fact that it goes off very far to the right on my screen is
> not terribly
> pleasing to my eyes (and can be rude for other developers).

> I was thinking of splitting it up like so:
> log.msg("Item wrote to MongoDB database %s/%s"
> %(settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
> level=log.DEBUG, spider=spider)

> Is this ok? Are there any rules in Python when it comes to breaking
> up long lines of
> code?

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

Hi Yves: 
PEP8 is your definitive guide for style questions: 
 

and this is an interesting set of notes: 

 

Basic rule is to break within parenthesis -- after that it becomes a matter of 
personal taste/style. 

In your specific example, I would do something like: 
log.msg( 
"Item wrote to MongoDB database %s %s" % ( 
settings['MONGODB_DB'], 
settings['MONGODB_COLLECTION]), 
level=log.DEBUG, 
spider=spider) 

Though you might want to: 
a) start your string right after the log.msg( 
b) put more than one settings on the same line 
c) put the last two parameters on the same line. 

I find that once I start breaking up lines for length, that I prefer to break 
up everything. 

Also remember when entering long lines of text that strings concatenate within 
parenthesis. 
So, 
("a, b, c" 
"d, e, f" 
"g, h, i") 

Is the same as ("a, b, cd, e, fg, h, i") 

--Ray 

-- 

Ray Cote, President 
Appropriate Solutions, Inc. 
We Build Software 
603.924.6079 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: n00b question on spacing

2013-06-21 Thread Yves S. Garret
On Fri, Jun 21, 2013 at 5:48 PM, Ray Cote
wrote:

>
> --
>
> *From: *"Yves S. Garret" 
> *To: *python-list@python.org
> *Sent: *Friday, June 21, 2013 5:17:28 PM
> *Subject: *n00b question on spacing
>
>
> Hi, I have a question about breaking up really long lines of code in
> Python.
>
> I have the following line of code:
> log.msg("Item wrote to MongoDB database %s/%s" %(settings['MONGODB_DB'],
> settings['MONGODB_COLLECTION']), level=log.DEBUG, spider=spider)
>
> Given the fact that it goes off very far to the right on my screen is not
> terribly
> pleasing to my eyes (and can be rude for other developers).
>
> I was thinking of splitting it up like so:
> log.msg("Item wrote to MongoDB database %s/%s"
>   %(settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
>   level=log.DEBUG, spider=spider)
>
> Is this ok?  Are there any rules in Python when it comes to breaking up
> long lines of
> code?
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>
>
> Hi Yves:
> PEP8 is your definitive guide for style questions:
>   
>
> and this is an interesting set of notes:
>   <
> http://stackoverflow.com/questions/5931297/how-would-you-properly-break-this-line-to-match-pep8-rules
> >
>
>
> Basic rule is to break within parenthesis -- after that it becomes a
> matter of personal taste/style.
>
> In your specific example, I would do something like:
> log.msg(
> "Item wrote to MongoDB database %s %s" % (
>
> settings['MONGODB_DB'],
> settings['MONGODB_COLLECTION]),
> level=log.DEBUG,
> spider=spider)
>
> Though you might want to:
> a) start your string right after the log.msg(
> b) put more than one settings on the same line
> c) put the last two parameters on the same line.
>
> I find that once I start breaking up lines for length, that I prefer to
> break up everything.
>
> Also remember when entering long lines of text that strings concatenate
> within parenthesis.
> So,
> ("a, b, c"
> "d, e, f"
> "g, h, i")
>
> Is the same as ("a, b, cd, e, fg, h, i")
>
> --Ray
>
> --
> Ray Cote, President
> Appropriate Solutions, Inc.
> We Build Software
> 603.924.6079
>

Thanks for your reply Ray.  My concern was that if I were to break with
something like this:
  log.msg("Item written to MongoDB database %s/%s"
%(settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
level = log.DEBUG, spider = spider)

I would get some undefined behaviour (the % is a little before the log.msg).

I'll read the links that you provided in order to learn more.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: n00b question on spacing

2013-06-21 Thread Gary Herron

On 06/21/2013 02:17 PM, Yves S. Garret wrote:
Hi, I have a question about breaking up really long lines of code in 
Python.


I have the following line of code:
log.msg("Item wrote to MongoDB database %s/%s" 
%(settings['MONGODB_DB'], settings['MONGODB_COLLECTION']), 
level=log.DEBUG, spider=spider)


Given the fact that it goes off very far to the right on my screen is 
not terribly

pleasing to my eyes (and can be rude for other developers).

I was thinking of splitting it up like so:
log.msg("Item wrote to MongoDB database %s/%s"
  %(settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
  level=log.DEBUG, spider=spider)

Is this ok?  Are there any rules in Python when it comes to breaking 
up long lines of

code?


This is how I'd do it:  (And it's *FAR* clearer -- You win no points for 
clarity by having it all in one statement.)


fmt  = "Item wrote to MongoDB database %s/%s"
msg = fmt % (settings['MONGODB_DB'],
 settings['MONGODB_COLLECTION'])
log.msg(msg, level=log.DEBUG, spider=spider)

Gary Herron

--
Dr. Gary Herron
Department of Computer Science
DigiPen Institute of Technology
(425) 895-4418

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


Re: n00b question on spacing

2013-06-21 Thread Terry Reedy

On 6/21/2013 5:17 PM, Yves S. Garret wrote:

Hi, I have a question about breaking up really long lines of code in Python.

I have the following line of code:
log.msg("Item wrote to MongoDB database %s/%s" %(settings['MONGODB_DB'],
settings['MONGODB_COLLECTION']), level=log.DEBUG, spider=spider)

Given the fact that it goes off very far to the right on my screen is
not terribly
pleasing to my eyes (and can be rude for other developers).

I was thinking of splitting it up like so:
log.msg("Item wrote to MongoDB database %s/%s"
   %(settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
   level=log.DEBUG, spider=spider)

Is this ok?  Are there any rules in Python when it comes to breaking up
long lines of code?


For function calls, PEP8 suggests either an extra indent or line up as 
follows.

log.msg("Item wrote to MongoDB database %s/%s"
%(settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
level=log.DEBUG, spider=spider)

The point is to not look like a normal indent to clue reader that these 
are continuation lines and not new statements.


--
Terry Jan Reedy

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


Re: Default Value

2013-06-21 Thread MRAB

On 21/06/2013 21:44, Rick Johnson wrote:

On Friday, June 21, 2013 2:25:49 PM UTC-5, MRAB wrote:

On 21/06/2013 19:26, Rick Johnson wrote:
> 
>   The Apathetic Approach:
> 
> I could just assume that a programmer is responsible for the
> code he writes. If he passes mutables into a function as
> default arguments, and then mutates the mutable later, too
> bad, he'll understand the value of writing solid code after
> a few trips to exception Hell.
> 
>   The Malevolent Approach (disguised as beneva-loon-icy):
> 
> I could use early binding to confuse the hell out of him and
> enjoy the laughs with all my ivory tower buddies as he falls
> into fits of confusion and rage. Then enjoy again when he
> reads the docs. Ahh, the gift that just keeps on giving!

How does the "Apathetic Approach" differ from the
"Malevolent Approach"?


In the apathetic approach i allow the programmer to be the
sole proprietor of his own misfortunes. He lives by the
sword, and thus, he can die by the sword.

Alternatively the malevolent approach injects misfortunes
for the programmer on the behalf of esoteric rules. In this
case he will live by sword, and he could die by the sword,
or he could be unexpectedly blown to pieces by a supersonic
Howitzer shell.

It's an Explicit death versus an Implicit death; and Explicit
should ALWAYS win!

The only way to strike a reasonable balance between the
explicit death and implicit death is to throw up a warning:

  "INCOMING"

Which in Python would be the "MutableArgumentWarning".

*school-bell*


I notice that you've omitted any mention of how you'd know that the
argument was mutable.

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


Re: Default Value

2013-06-21 Thread Rotwang

On 21/06/2013 19:26, Rick Johnson wrote:

On Friday, June 21, 2013 12:47:56 PM UTC-5, Rotwang wrote:

It isn't clear to me from your posts what exactly you're
proposing as an alternative to the way Python's default
argument binding works. In your version of Python, what
exactly would happen when I passed a mutable argument as a
default value in a def statement? E.g. this:

  >>> a = [1, 2, 3]
  >>> a.append(a)
  >>> b = object()
  >>> def f(x = [None, b, [a, [4]]]):
... pass # do something

What would you like to see the interpreter do in this case?


Ignoring that this is a completely contrived example that has
no use in the real world, here are one of three methods by
which i can handle this:


I didn't ask what alternative methods of handling default argument 
binding exist (I can think of several, but none of them strikes me as 
preferable to how Python currently does it). I asked what would happen 
in /your/ version of Python. Which of the alternatives that you present 
would have been implemented, if you had designed the language?





  The Benevolent Approach:

I could cast a "virtual net" over my poor lemmings before
they jump off the cliff by throwing an exception:

   Traceback (most recent screw-up last):
Line BLAH in SCRIPT
 def f(x = [None, b, [a, [4]]]):
   ArgumentError: No mutable default arguments allowed!


So how does the interpreter know whether an arbitrary object passed as a 
default value is mutable or not?


Not that it really matters. Elsewhere in this thread you wrote:


Let's imagine for a second if Python allowed mutable keys in
a dictionary,


which it does


would you be surprised if you used a mutable
for a key, then you mutated the mutable key, then you could
not access the value from the original key?

 ## Imaginary code ##
 py> lst = [3]
 py> d = {1:2, lst:4}
 py> lst.append(10)
 py> d[lst]
 opps, KeyError!

Would you REALLY be so surprised? I would not. But more
importantly, does Python need to protect you from being such
an idiot? I don't think so!


Now, I don't really believe that you think that the user shouldn't be 
protected from doing one idiotic thing with mutable dict keys but should 
be protected from doing another idiotic thing with mutable default 
arguments, especially as you've already been given a use case for the 
latter. So I assume that The Benevolent Approach is not the approach you 
would have gone for if you had designed the language, right? If so then 
let's ignore it.





  The Apathetic Approach:

I could just assume that a programmer is responsible for the
code he writes. If he passes mutables into a function as
default arguments, and then mutates the mutable later, too
bad, he'll understand the value of writing solid code after
a few trips to exception Hell.


It seems to me that this is exactly what currently happens.




  The Malevolent Approach (disguised as beneva-loon-icy):

I could use early binding to confuse the hell out of him and
enjoy the laughs with all my ivory tower buddies as he falls
into fits of confusion and rage. Then enjoy again when he
reads the docs. Ahh, the gift that just keeps on giving!


My question was about how you think the language should work, not about 
what your buddies should or shouldn't enjoy. In terms of how a language 
actually works, is there any difference between The Malevolent Approach 
and The Apathetic Approach? And is there any difference between either 
of them and what Python currently does?





  Conclusion:

As you can probably guess the malevolent approach has some
nice fringe benefits.

You know, out of all these post, not one of you guys has
presented a valid use-case that will give validity to the
existence of this PyWart -- at least not one that CANNOT be
reproduced by using my fine examples.


Of course using a mutable default as a cache can be reproduced by other 
means, as can another common use case that I don't think anyone's 
mentioned yet (defining functions parametrised by variables whose values 
aren't known until runtime). That's hardly an argument against it - you 
might as well argue that Python shouldn't have decorators, or that it 
shouldn't have for loops because their behaviour can be reproduced with 
while loops.


But this is beside the point anyway, until you present an alternative to 
Python's current behaviour. If you do so then we can start debating the 
relative merits of the two approaches.

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


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 5:49:51 PM UTC-5, MRAB wrote:
> I notice that you've omitted any mention of how you'd know that the
> argument was mutable.

My argument has always been that mutables should not be
passed into subroutines as default arguments because bad
things can happen. And Python's excuse of saving the poor
dummies is no excuse.

It does not matter if we are passing the arguments into the
current implementation of "python functions which maintain
state of default mutables arguments between successive
calls" or in a more desirable system of truly "stateless
subroutines".

I also believe that a programmer should not be prevented
from passing mutable default arguments, but if he does, I'm
not going to provide any sort of protection -- other than
possibly throwing up a warning message.

Now, YOU, and everyone else, cannot destroy the main points
of my argument because the points are in fact rock solid,
however, what you will do is to focus in one small detail,
one little tiny (perceived) weakness in the armor, and you
will proceed to destroy that small detail (in this case how
i will determine mutability), and hope that the destruction
of this insignificant detail will start a chain-reaction
that will propagate out and bring down my entire position.

So you want me to tell you how to query the mutability of an
object... Ha Ha Ha! Sorry, but that's not going to happen!

Why should i help the developers of this language. What have
they done for me?  Hmm, let's see. They called me names.
Trolled up my posts. Written me off. Refused to answer my
questions. Been absolutely rude. etc, etc... Banned me from
lists i've never posted on and then proclaim the list is
free and open to all... BS!

WOULD YOU OFFER ASSISTANCE TO PEOPLE THAT HAVE TREATED YOU THIS WAY?  
 
And let's just be honest. You don't want my assistance. You
just want me to fumble the ball. Then you can use that
fumble as an excuse to write me off. Nice try!

You want to gain my respect? Then start engaging in honest
debates. Start admitting that yes, somethings about Python
are not only undesirable, they're just plain wrong. 

Stop calling me a troll when i am not. And not just me, stop
calling other people trolls too! Stop using the personal
attacks and straw man arguments.  

Finally, get the core devs to realize that this list matters
and they need to participate (including you know who!)

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


Re: Default Value

2013-06-21 Thread Steven D'Aprano
On Fri, 21 Jun 2013 23:49:51 +0100, MRAB wrote:

> On 21/06/2013 21:44, Rick Johnson wrote:
[...]
>> Which in Python would be the "MutableArgumentWarning".
>>
>> *school-bell*
>>
> I notice that you've omitted any mention of how you'd know that the
> argument was mutable.

That's easy. Just call ismutable(arg). The implementation of ismutable is 
just an implementation detail, somebody else can work that out. A 
language designer of the sheer genius of Rick can hardly be expected to 
worry himself about such trivial details.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 6:40:51 PM UTC-5, Rotwang wrote:
> On 21/06/2013 19:26, Rick Johnson wrote:
> [...]
> I didn't ask what alternative methods of handling default
> argument binding exist (I can think of several, but none
> of them strikes me as preferable to how Python currently
> does it). I asked what would happen in /your/ version of
> Python. Which of the alternatives that you present would
> have been implemented, if you had designed the language?

The apathetic approach. However, you fail to understand that
whilst Python's current implementation is partly apathetic,
is is also benevolent, and malevolent simultaneously. My
approach is purely apathetic. I'll explain later. Stay
tuned.

> [...]
> So how does the interpreter know whether an arbitrary
> object passed as a default value is mutable or not? Not
> that it really matters.

Well i'm glad it does not matter to you because it does not
matter to me either. *shrugs*

> > Let's imagine for a second if Python allowed mutable keys in
> > a dictionary,
> which it does

Am i just to take your word for this? You cannot provide an
example? Here, allow me to "break the ice":

# Literal
py> d = {[1]:2}
Traceback (most recent call last):
  File "", line 1, in 
d = {[1]:2}
TypeError: unhashable type: 'list'
# Symbol
py> lst = [1]
py> d = {lst:2}
Traceback (most recent call last):
  File "", line 1, in 
d = {lst:2}
TypeError: unhashable type: 'list'

Hmm, maybe only certain mutables work? Great, more esoteric
rules! Feel free to enlighten me since i'm not going to
waste one second of my time pursuing the docs just to learn
about ANOTHER unintuitive PyWart i have no use for.

> Now, I don't really believe that you think that the user
> shouldn't be protected from doing one idiotic thing with
> mutable dict keys but should be protected from doing
> another idiotic thing with mutable default arguments,
> especially as you've already been given a use case for the
> latter. So I assume that The Benevolent Approach is not
> the approach you would have gone for if you had designed
> the language, right? If so then let's ignore it.

You are correct. Finally, we can agree on something.

> > 
> >   The Apathetic Approach:
> > 
> > I could just assume that a programmer is responsible for the
> > code he writes. If he passes mutables into a function as
> > default arguments, and then mutates the mutable later, too
> > bad, he'll understand the value of writing solid code after
> > a few trips to exception Hell.
>
> It seems to me that this is exactly what currently happens.

(is this lazy readers day? I swear i explained this earlier)

And here is where you are wrong. In the current implementation
python functions carry the state of mutable default arguments
between successive calls. That's a flaw. Observe:

py> def foo(arg=[]):
... arg.append(1)
... print(arg)
...
py> foo()
[1]
py> foo()
[1, 1]
py> foo()
[1, 1, 1]

No, no, NO! That's wrong! Subroutines should be stateless.
That means that an empty mutable default argument will
ALWAYS be empty at each call of the subroutine.  This is
what should happen:

py> def foo(arg=[]):
... arg.append(1)
... print(arg)
...
py> foo()
[1]
py> foo()
[1]
py> foo()
[1]

Yes, Yes, YES! That is intuitive! That is sane! Now, what if
we pass a reference to a mutable object? What then. Well, let's
see:

py> lst = range(5)
py> lst
[0, 1, 2, 3, 4]
py> def foo(arg=lst):
... arg.append(1)
... print(arg)
...
py> foo()
[0, 1, 2, 3, 4, 1]
py> foo()
[0, 1, 2, 3, 4, 1, 1]

That's fine. Because the object was already created OUTSIDE
the subroutine. So therefore, modifications to the mutable
are not breaking the fundamental of statelessness INSIDE
subroutines. The modification is merely a side effect, and
the subroutine is unconcerned with anything that exists
beyond it's own scope.

IS ALL THIS REGISTERING YET? DO YOU UNDERSTAND?

> > 
> >   The Malevolent Approach (disguised as beneva-loon-icy):
> > 
> > I could use early binding to confuse the hell out of him and
> > enjoy the laughs with all my ivory tower buddies as he falls
> > into fits of confusion and rage. Then enjoy again when he
> > reads the docs. Ahh, the gift that just keeps on giving!
> My question was about how you think the language should
> work, not about what your buddies should or shouldn't
> enjoy.

My buddies? This design flaw is NOT my brain child. Your
barking up the wrong tree pal.

> In terms of how a language actually works, is there
> any difference between The Malevolent Approach and The
> Apathetic Approach? And is there any d

Re: Default Value

2013-06-21 Thread Ian Kelly
On Fri, Jun 21, 2013 at 7:15 PM, Steven D'Aprano
 wrote:
> On Fri, 21 Jun 2013 23:49:51 +0100, MRAB wrote:
>
>> On 21/06/2013 21:44, Rick Johnson wrote:
> [...]
>>> Which in Python would be the "MutableArgumentWarning".
>>>
>>> *school-bell*
>>>
>> I notice that you've omitted any mention of how you'd know that the
>> argument was mutable.
>
> That's easy. Just call ismutable(arg). The implementation of ismutable is
> just an implementation detail, somebody else can work that out. A
> language designer of the sheer genius of Rick can hardly be expected to
> worry himself about such trivial details.

While we're at it, I would like to petition for a function
terminates(f, args) that I can use to determine whether a function
will terminate before I actually call it.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: n00b question on spacing

2013-06-21 Thread Steven D'Aprano
On Fri, 21 Jun 2013 17:48:54 -0400, Ray Cote wrote:

> Also remember when entering long lines of text that strings concatenate
> within parenthesis. So,
> ("a, b, c"
> "d, e, f"
> "g, h, i")
> 
> Is the same as ("a, b, cd, e, fg, h, i")


Technically, you don't need the parentheses. You can also use backslash 
to continue the lines:


s = "a, b, c, " \
"d, e, f, " \
"g, h, i"
assert s == "a, b, c, d, e, f, g, h, i"


Or, if the strings are small enough, fit them on one line:

s = "a" "b" "c"

This *implicit concatenation* only works with string literals, not 
variables, but it works with any sort of quoting style:

s = "-'-" '-"-' r"\a\b"
assert s == "-'--\"-\\a\\b"


Like most such features, a little goes a long way. Don't over do it, it 
is quite possible to end up with an unreadable mess if you overuse it.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Steven D'Aprano
On Sat, 22 Jun 2013 05:07:59 +1000, Chris Angelico wrote:

> Oh! I know. Function argument defaults will now be restricted to
> int/float/tuple. That would do it, right? Nobody would be bothered by
> little restrictions like that, would they.

Alas, tuples won't do it. Fortunately, you can include str and bytes 
(unicode and str) and frozenset in the "Good List". Tuples have to go 
into the "Bad List" because, although they themselves are immutable, 
their contents may not be. Imagine the confusion and horror that poor 
developers will experience when they do something like this:

def func(arg, extra=(23, 'foo', [])):
[code goes here...]
extra[2].append("something")
[more code...]


and they've now mutated the immutable default!

Thinking about this, I think that the only safe thing to do in Rickython 
4000 is to prohibit putting mutable objects inside tuples. Putting a list 
or a dict inside a tuple is just a bug waiting to happen!

-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Chris Angelico
On Sat, Jun 22, 2013 at 11:15 AM, Rick Johnson
 wrote:
> # Literal
> py> d = {[1]:2}
> Traceback (most recent call last):
>   File "", line 1, in 
> d = {[1]:2}
> TypeError: unhashable type: 'list'
> # Symbol
> py> lst = [1]
> py> d = {lst:2}
> Traceback (most recent call last):
>   File "", line 1, in 
> d = {lst:2}
> TypeError: unhashable type: 'list'
>
> Hmm, maybe only certain mutables work? Great, more esoteric
> rules! Feel free to enlighten me since i'm not going to
> waste one second of my time pursuing the docs just to learn
> about ANOTHER unintuitive PyWart i have no use for.

>>> class HashableList(list):
def __hash__(self):
return 42

>>> a=HashableList()
>>> a
[]
>>> a.append(1)
>>> a.append(2)
>>> a.append(3)
>>> a
[1, 2, 3]
>>> d={a:123}
>>> d
{[1, 2, 3]: 123}
>>> a.append(4)
>>> d[a]
123

It's nothing to do with mutability, all to do with hashability. And
you can pick a number of different ways of hashing these objects, like
going for the object's id(), or attempting to hash tuple(self) and
falling back on id(), or anything you like. Easy.

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


Re: Default Value

2013-06-21 Thread Chris Angelico
On Sat, Jun 22, 2013 at 11:31 AM, Steven D'Aprano
 wrote:
> Thinking about this, I think that the only safe thing to do in Rickython
> 4000 is to prohibit putting mutable objects inside tuples. Putting a list
> or a dict inside a tuple is just a bug waiting to happen!

I think you're onto something here, but you really haven't gone far
enough. Mutable objects *anywhere* are a problem. The solution?
Abolish mutable objects. Strings (bytes and Unicode), integers,
decimals (floats are a problem to many people), tuples of the above,
and dictionaries mapping any of the above to any other of the above,
should be enough to do everything.

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


Re: Default Value

2013-06-21 Thread Chris Angelico
On Sat, Jun 22, 2013 at 11:27 AM, Ian Kelly  wrote:
> On Fri, Jun 21, 2013 at 7:15 PM, Steven D'Aprano
>  wrote:
>> On Fri, 21 Jun 2013 23:49:51 +0100, MRAB wrote:
>>
>>> On 21/06/2013 21:44, Rick Johnson wrote:
>> [...]
 Which in Python would be the "MutableArgumentWarning".

 *school-bell*

>>> I notice that you've omitted any mention of how you'd know that the
>>> argument was mutable.
>>
>> That's easy. Just call ismutable(arg). The implementation of ismutable is
>> just an implementation detail, somebody else can work that out. A
>> language designer of the sheer genius of Rick can hardly be expected to
>> worry himself about such trivial details.
>
> While we're at it, I would like to petition for a function
> terminates(f, args) that I can use to determine whether a function
> will terminate before I actually call it.

Nice idea from a theoretical point of view, but practicality beats
purity, and most people know their functions will terminate (that's
what Ctrl-C is for). No, I want a function isbuggy(f) to find out
whether a function is, well, buggy. We could abolish all unit-testing
if we had that.

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


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 8:31:35 PM UTC-5, Steven D'Aprano wrote:
> Tuples have to go into the "Bad List" because, although
> they themselves are immutable, their contents may not be.
> Imagine the confusion and horror that poor developers will
> experience when they do something like this:
> 
> def func(arg, extra=(23, 'foo', [])):
> [code goes here...]
> extra[2].append("something")
> [more code...]
>
> and they've now mutated the immutable default! Thinking
> about this, I think that the only safe thing to do in
> Rickython 4000 is to prohibit putting mutable objects
> inside tuples. Putting a list or a dict inside a tuple is
> just a bug waiting to happen!

Geezsus, the warts in this language are innumerable! 

So what your saying is that Python Tuples are "immutable"
like automobiles passengers are "immutable". Sure you can
design the car for a maximum number of passengers, but as
soon as the circus clowns show up, all bets are off!

This whole language is a joke! It just some sick joke! ROTF
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Ian Kelly
On Fri, Jun 21, 2013 at 7:15 PM, Rick Johnson
 wrote:
>> > Let's imagine for a second if Python allowed mutable keys in
>> > a dictionary,
>> which it does
>
> Am i just to take your word for this? You cannot provide an
> example? Here, allow me to "break the ice":
>
> # Literal
> py> d = {[1]:2}
> Traceback (most recent call last):
>   File "", line 1, in 
> d = {[1]:2}
> TypeError: unhashable type: 'list'
> # Symbol
> py> lst = [1]
> py> d = {lst:2}
> Traceback (most recent call last):
>   File "", line 1, in 
> d = {lst:2}
> TypeError: unhashable type: 'list'
>
> Hmm, maybe only certain mutables work? Great, more esoteric
> rules! Feel free to enlighten me since i'm not going to
> waste one second of my time pursuing the docs just to learn
> about ANOTHER unintuitive PyWart i have no use for.

The answer to this conundrum is staring you in the face.  Note that
the TypeError complains that you passed it an "unhashable" type, and
not that you passed it a "mutable" type.  If you want to take a
mutable type and make it hashable, just add a __hash__ method.

class HashableList(list):
def __hash__(self):
return 42

>>> d = dict()
>>> hl = HashableList(range(5))
>>> hl2 = HashableList(range(6, 10))
>>> d[hl] = 10
>>> d[hl2] = 20
>>> d
{[0, 1, 2, 3, 4]: 10, [6, 7, 8, 9]: 20}

Additionally, instances of user-defined classes are, by default, both
mutable and hashable.  This is safe because equality and hashing for
such objects are by default based on identity.  If you override the
__eq__ method though, then you lose hashability unless you explicitly
override __hash__ as well.
>
>> Now, I don't really believe that you think that the user
>> shouldn't be protected from doing one idiotic thing with
>> mutable dict keys but should be protected from doing
>> another idiotic thing with mutable default arguments,
>> especially as you've already been given a use case for the
>> latter. So I assume that The Benevolent Approach is not
>> the approach you would have gone for if you had designed
>> the language, right? If so then let's ignore it.
>
> You are correct. Finally, we can agree on something.
>
>> > 
>> >   The Apathetic Approach:
>> > 
>> > I could just assume that a programmer is responsible for the
>> > code he writes. If he passes mutables into a function as
>> > default arguments, and then mutates the mutable later, too
>> > bad, he'll understand the value of writing solid code after
>> > a few trips to exception Hell.
>>
>> It seems to me that this is exactly what currently happens.
>
> (is this lazy readers day? I swear i explained this earlier)
>
> And here is where you are wrong. In the current implementation
> python functions carry the state of mutable default arguments
> between successive calls. That's a flaw. Observe:
>
> py> def foo(arg=[]):
> ... arg.append(1)
> ... print(arg)
> ...
> py> foo()
> [1]
> py> foo()
> [1, 1]
> py> foo()
> [1, 1, 1]
>
> No, no, NO! That's wrong! Subroutines should be stateless.
> That means that an empty mutable default argument will
> ALWAYS be empty at each call of the subroutine.  This is
> what should happen:
>
> py> def foo(arg=[]):
> ... arg.append(1)
> ... print(arg)
> ...
> py> foo()
> [1]
> py> foo()
> [1]
> py> foo()
> [1]
>
> Yes, Yes, YES! That is intuitive! That is sane! Now, what if
> we pass a reference to a mutable object? What then. Well, let's
> see:
>
> py> lst = range(5)
> py> lst
> [0, 1, 2, 3, 4]
> py> def foo(arg=lst):
> ... arg.append(1)
> ... print(arg)
> ...
> py> foo()
> [0, 1, 2, 3, 4, 1]
> py> foo()
> [0, 1, 2, 3, 4, 1, 1]
>
> That's fine. Because the object was already created OUTSIDE
> the subroutine. So therefore, modifications to the mutable
> are not breaking the fundamental of statelessness INSIDE
> subroutines. The modification is merely a side effect, and
> the subroutine is unconcerned with anything that exists
> beyond it's own scope.
>
> IS ALL THIS REGISTERING YET? DO YOU UNDERSTAND?
>
>> > 
>> >   The Malevolent Approach (disguised as beneva-loon-icy):
>> > 
>> > I could use early binding to confuse the hell out of him and
>> > enjoy the laughs with all my ivory tower buddies as he falls
>> > into fits of confusion and rage. Then enjoy again when he
>> > reads the docs. Ahh, the gift that just keeps on giving!
>> My question was about how you think the language should
>> work, not about what your buddies should or shouldn't
>> enjoy.
>
> My buddies? This design flaw is NOT my brain child. Your
> barking up the wrong tree pal.
>
>> In terms of how a language actually works, is th

Re: Default Value

2013-06-21 Thread Ian Kelly
On Fri, Jun 21, 2013 at 7:37 PM, Chris Angelico  wrote:
 class HashableList(list):
> def __hash__(self):
> return 42

Hey, we both picked exactly the same example!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread MRAB

On 22/06/2013 00:51, Rick Johnson wrote:

On Friday, June 21, 2013 5:49:51 PM UTC-5, MRAB wrote:

I notice that you've omitted any mention of how you'd know that the
argument was mutable.


My argument has always been that mutables should not be
passed into subroutines as default arguments because bad
things can happen. And Python's excuse of saving the poor
dummies is no excuse.

It does not matter if we are passing the arguments into the
current implementation of "python functions which maintain
state of default mutables arguments between successive
calls" or in a more desirable system of truly "stateless
subroutines".

I also believe that a programmer should not be prevented
from passing mutable default arguments, but if he does, I'm
not going to provide any sort of protection -- other than
possibly throwing up a warning message.


So, having mutables as default arguments is a bad idea, but a
programmer should not be prevented from doing that, and a warning
message should be printed on such occasions.


Now, YOU, and everyone else, cannot destroy the main points
of my argument because the points are in fact rock solid,
however, what you will do is to focus in one small detail,
one little tiny (perceived) weakness in the armor, and you
will proceed to destroy that small detail (in this case how
i will determine mutability), and hope that the destruction
of this insignificant detail will start a chain-reaction
that will propagate out and bring down my entire position.


In order to print a warning, Python needs to know whether the object is
mutable, so it's an important detail.


So you want me to tell you how to query the mutability of an
object... Ha Ha Ha! Sorry, but that's not going to happen!


It's a detail that you're not going to help to solve.


Why should i help the developers of this language. What have
they done for me?


They've developed this language, and provided it for free. They've even
released the source code.

You perceive flaws that you say must be fixed, but you're not going to
help to fix them.


WOULD YOU OFFER ASSISTANCE TO PEOPLE THAT HAVE TREATED YOU THIS WAY?

And let's just be honest. You don't want my assistance. You
just want me to fumble the ball. Then you can use that
fumble as an excuse to write me off. Nice try!


I _do_ want you to help to improve the language, and I don't care if
you don't get it right first time. I didn't get it right first time
when I worked on the regex module (I think that what I have on PyPI is
my _third_ attempt!).


You want to gain my respect? Then start engaging in honest
debates. Start admitting that yes, somethings about Python
are not only undesirable, they're just plain wrong.


Python isn't perfect, but then no language is perfect. There will
always be compromises, and the need to maintain backwards compatibility
means that we're stuck with some "mis-features", but I think it's still
worth using; I still much prefer it to other languages.


Stop calling me a troll when i am not. And not just me, stop
calling other people trolls too! Stop using the personal
attacks and straw man arguments.


???


Finally, get the core devs to realize that this list matters
and they need to participate (including you know who!)


Everyone is a volunteer. The core devs contribute by developing the
language, and whether they participate in this particular list is
entirely up to them; how they choose to spend _their own_ free time is,
again, entirely up to them.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread MRAB

On 22/06/2013 02:40, Chris Angelico wrote:

On Sat, Jun 22, 2013 at 11:31 AM, Steven D'Aprano
 wrote:

Thinking about this, I think that the only safe thing to do in Rickython
4000 is to prohibit putting mutable objects inside tuples. Putting a list
or a dict inside a tuple is just a bug waiting to happen!


I think you're onto something here, but you really haven't gone far
enough. Mutable objects *anywhere* are a problem. The solution?
Abolish mutable objects. Strings (bytes and Unicode), integers,
decimals (floats are a problem to many people), tuples of the above,
and dictionaries mapping any of the above to any other of the above,
should be enough to do everything.


Pure functional languages don't have mutables, or even variables, but
then we're not talking about a pure functional language, we're talking
about Python.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Rotwang

On 22/06/2013 02:15, Rick Johnson wrote:

On Friday, June 21, 2013 6:40:51 PM UTC-5, Rotwang wrote:

On 21/06/2013 19:26, Rick Johnson wrote:
[...]
I didn't ask what alternative methods of handling default
argument binding exist (I can think of several, but none
of them strikes me as preferable to how Python currently
does it). I asked what would happen in /your/ version of
Python. Which of the alternatives that you present would
have been implemented, if you had designed the language?


The apathetic approach. However, you fail to understand that
whilst Python's current implementation is partly apathetic,
is is also benevolent, and malevolent simultaneously. My
approach is purely apathetic. I'll explain later. Stay
tuned.


OK...



[...]
So how does the interpreter know whether an arbitrary
object passed as a default value is mutable or not? Not
that it really matters.


Well i'm glad it does not matter to you because it does not
matter to me either. *shrugs*


Let's imagine for a second if Python allowed mutable keys in
a dictionary,

which it does


Am i just to take your word for this? You cannot provide an
example?


Of course I can:

>>> class hashablelist(list):
... def __hash__(self):
... return hash(tuple(self))
... 
>>> x = hashablelist(range(4))
>>> x
[0, 1, 2, 3]
>>> # Let's try using x as a dict key:
>>> d = {x: 'Hello'}
>>> d[x]
'Hello'
>>> # Let's try mutating it:
>>> x.append(4)
>>> x
[0, 1, 2, 3, 4]



Here, allow me to "break the ice":

 # Literal
 py> d = {[1]:2}
 Traceback (most recent call last):
   File "", line 1, in 
 d = {[1]:2}
 TypeError: unhashable type: 'list'
 # Symbol
 py> lst = [1]
 py> d = {lst:2}
 Traceback (most recent call last):
   File "", line 1, in 
 d = {lst:2}
 TypeError: unhashable type: 'list'

Hmm, maybe only certain mutables work?


Try reading the tracebacks. Notice how they don't say anything about 
mutability?




Great, more esoteric
rules! Feel free to enlighten me since i'm not going to
waste one second of my time pursuing the docs just to learn
about ANOTHER unintuitive PyWart i have no use for.


Sure. In order to be used as a dictionary key a Python has to be 
hashable. That means its type has to define a __hash__ method, which is 
called by the builtin function hash. The __hash__ method should return 
an int, and objects that compare equal should have the same hash.




Now, I don't really believe that you think that the user
shouldn't be protected from doing one idiotic thing with
mutable dict keys but should be protected from doing
another idiotic thing with mutable default arguments,
especially as you've already been given a use case for the
latter. So I assume that The Benevolent Approach is not
the approach you would have gone for if you had designed
the language, right? If so then let's ignore it.


You are correct. Finally, we can agree on something.



   The Apathetic Approach:

I could just assume that a programmer is responsible for the
code he writes. If he passes mutables into a function as
default arguments, and then mutates the mutable later, too
bad, he'll understand the value of writing solid code after
a few trips to exception Hell.


It seems to me that this is exactly what currently happens.


(is this lazy readers day? I swear i explained this earlier)

And here is where you are wrong. In the current implementation
python functions carry the state of mutable default arguments
between successive calls. That's a flaw.


But your description of The Apathetic Approach doesn't say anything 
about functions carrying the state of mutable default arguments, or 
otherwise. How am I supposed to know how your proposed approach treats 
mutable defaults if you don't tell me, even after I explicitly ask?




Observe:

 py> def foo(arg=[]):
 ... arg.append(1)
 ... print(arg)
 ...
 py> foo()
 [1]
 py> foo()
 [1, 1]
 py> foo()
 [1, 1, 1]


Yes, I am well aware of how Python currently treats mutable default 
arguments.




No, no, NO! That's wrong! Subroutines should be stateless.
That means that an empty mutable default argument will
ALWAYS be empty at each call of the subroutine.  This is
what should happen:

 py> def foo(arg=[]):
 ... arg.append(1)
 ... print(arg)
 ...
 py> foo()
 [1]
 py> foo()
 [1]
 py> foo()
 [1]

Yes, Yes, YES! That is intuitive! That is sane! Now, what if
we pass a reference to a mutable object? What then. Well, let's
see:

 py> lst = range(5)
 py> lst
 [0, 1, 2, 3, 4]
 py> def foo(arg=lst):
 ... arg.append(1)
 ... print(arg)
 ...
 py> foo()
 [0, 1, 2, 3, 4, 1]
 py> foo()
 [0, 1, 2, 3, 4, 1, 1]

That's fine. Because the object was already created OUTSIDE
the subroutine. So therefore, 

Re: Default Value

2013-06-21 Thread Chris Angelico
On Sat, Jun 22, 2013 at 12:01 PM, Rotwang  wrote:
 class hashablelist(list):
> ... def __hash__(self):
> ... return hash(tuple(self))

There's a vulnerability in that definition:

>>> a=hashablelist((1,[],3))
>>> a
[1, [], 3]
>>> {a:1}
Traceback (most recent call last):
  File "", line 1, in 
{a:1}
  File "", line 3, in __hash__
return hash(tuple(self))
TypeError: unhashable type: 'list'

Of course, if you monkey-patch list itself to have this functionality,
or always use hashablelist instead of list, then it will work. But
it's still vulnerable.

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


Re: Default Value

2013-06-21 Thread Rotwang

On 22/06/2013 03:18, Chris Angelico wrote:

On Sat, Jun 22, 2013 at 12:01 PM, Rotwang  wrote:

class hashablelist(list):

... def __hash__(self):
... return hash(tuple(self))


There's a vulnerability in that definition:


a=hashablelist((1,[],3))
a

[1, [], 3]

{a:1}

Traceback (most recent call last):
   File "", line 1, in 
 {a:1}
   File "", line 3, in __hash__
 return hash(tuple(self))
TypeError: unhashable type: 'list'

Of course, if you monkey-patch list itself to have this functionality,
or always use hashablelist instead of list, then it will work. But
it's still vulnerable.


Quite right, sorry. I should have called my class 
"sometimeshashablelist", or something.


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


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 8:54:50 PM UTC-5, MRAB wrote:
> On 22/06/2013 00:51, Rick Johnson wrote:
> > On Friday, June 21, 2013 5:49:51 PM UTC-5, MRAB wrote:
> > My argument has always been that mutables should not be
> > passed into subroutines as default arguments because bad
> > things can happen. [...] I also believe that a programmer
> > should not be prevented from passing mutable default
> > arguments [...]
> So, having mutables as default arguments is a bad idea,
> but a programmer should not be prevented from doing that,
> and a warning message should be printed on such occasions.

Well i'll admit that does sound like a contradiction.
Basically i meant, programmers should be *discouraged* from
passing mutables as default arguments but not *prevented*.
Of course, utilizing a stateless subroutine like i suggest,
argument mutability would not matter.

Sometimes when you're passionate about something your
explanations become so verbose as to render your idea lost
in the noise. Obviously i made that mistake here :)

In my last reply to Rotwang i explained the functionality i
seek to achieve in a set of three interactive examples.
Take a look at those and let me know what you think.

> > Why should i help the developers of this language. What have
> > they done for me?
> 
> They've developed this language, and provided it for free.
> They've even released the source code. You perceive flaws
> that you say must be fixed, but you're not going to help
> to fix them.

Agreed. And i am thankful for everyone's contributions. I
can be a bit harsh sometimes but my intention has always
been to improve Python.

> I _do_ want you to help to improve the language, and I
> don't care if you don't get it right first time. I didn't
> get it right first time when I worked on the regex module
> (I think that what I have on PyPI is my _third_ attempt!).

Well thanks for admitting you are not perfect. I know i am
not. We all had to start somewhere and anyone who believes
he knows everything is most assuredly a fool. Learning is
a perpetual process, same for software evolution.

> > You want to gain my respect? Then start engaging in honest
> > debates. Start admitting that yes, somethings about Python
> > are not only undesirable, they're just plain wrong.
> Python isn't perfect, but then no language is perfect.
> There will always be compromises, and the need to maintain
> backwards compatibility means that we're stuck with some
> "mis-features", but I think it's still worth using; I
> still much prefer it to other languages.

I understand. We can't break backwards compatibility for
everything, even breaking it for some large flaws could
cause a fatal abandonment of the language by long time
users. 

I just don't understand why i get so much hostility when i
present the flaws for discussion. Part of my intention is to
air the flaw, both for new users and old users, but a larger
intention is to discover the validity of my, or others,
possible solutions.

And even if that solution involves a fork, that is not a bad
thing. Creating a new fork and then garnering an acceptance
of the new spinoff would lead to at worse, a waste of time
and a huge learning experience, or at best, an evolution of
the language.

> > Stop calling me a troll when i am not. And not just me, stop
> > calling other people trolls too! Stop using the personal
> > attacks and straw man arguments.

Sorry. I failed to explain that this statement was meant not
directly for you but as a general statement to all members.
Sometimes i feel like my back is against the wall and i'm
fighting several foes at once. That can lead to me getting
defensive.

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


Re: Default Value

2013-06-21 Thread rusi
On Saturday, June 22, 2013 6:57:42 AM UTC+5:30, Ian wrote:
> While we're at it, I would like to petition for a function
> terminates(f, args) that I can use to determine whether a function
> will terminate before I actually call it.

I was going to say something about this -- viz that in prog. languages 
sometimes things that look laughably easy can turn out HARD.

As a personal example of a time I found myself in Rick's shoes:

I was lecturing to some audience on the glories of FP. Someone asked me how 
efficient such a language would be.  I replied (rather cock-surely) that 
efficiency is not a property of languages but of implementations.

So someone got up and asked me: Ok lets say I add a new value-space to your 
language -- propositions, and a new operator -- sat -- that checks whether a 
proposition is satisfiable...

So Rick... I agree with you... all these theoreticians should be burnt at the 
stake!

On a more serious note: many people make similar mistakes eg Haskellers who 
think Haskell is safe.
Safer (than something or other) -- Ok
Safe -- NO
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 8:38:21 PM UTC-5, Ian wrote:
> The answer to this conundrum is staring you in the face.

Thanks for posting a solution for this. Not sure if i'll
ever need it, but nice to know.

> Note that the TypeError complains that you passed it an
> "unhashable" type, and not that you passed it a "mutable"
> type.  If you want to take a mutable type and make it
> hashable, just add a __hash__ method.
> 
> class HashableList(list):
> def __hash__(self):
> return 42
> >>> d = dict()
> >>> hl = HashableList(range(5))
> >>> hl2 = HashableList(range(6, 10))
> >>> d[hl] = 10
> >>> d[hl2] = 20
> >>> d
> {[0, 1, 2, 3, 4]: 10, [6, 7, 8, 9]: 20}
> 
> Additionally, instances of user-defined classes are, by
> default, both mutable and hashable.  This is safe because
> equality and hashing for such objects are by default based
> on identity.  If you override the __eq__ method though,
> then you lose hashability unless you explicitly override
> __hash__ as well.

Hey, you went above and beyond to provide that last bit of info. 
Thanks again!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread rusi
On Saturday, June 22, 2013 7:34:18 AM UTC+5:30, MRAB wrote:
> Pure functional languages don't have mutables, or even variables, but
> then we're not talking about a pure functional language, we're talking
> about Python.

In which case neither do mathematicians.  Do we rewrite the last 1000 years of 
math history?

The incantation:
x = x+1
is something algorithmists (ie programmers) write without batting an eyelid.

Algebraically (ie for a mathematician) this is the specification of an 
impossibility.

Every programmer needs to have both these modes of thinking -- algebraic and 
algorithmic -- up his sleeve.

Ironically it was al Khwarizmi -- whose name became 'algorithm' -- who wrote al 
Gebr -- from which we get algebra ie its taken us a millenium to come full 
circle!!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Michael Torrie
On 06/21/2013 07:41 PM, Chris Angelico wrote:
>> While we're at it, I would like to petition for a function
>> terminates(f, args) that I can use to determine whether a function
>> will terminate before I actually call it.
> 
> Nice idea from a theoretical point of view, but practicality beats
> purity, and most people know their functions will terminate (that's
> what Ctrl-C is for). No, I want a function isbuggy(f) to find out
> whether a function is, well, buggy. We could abolish all unit-testing
> if we had that.

That's awesome.  I laughed out loud when I read Ian's comment, though it
took me longer than I should have needed to notice your tongue firmly in
your cheek as well.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Default Value

2013-06-21 Thread Rick Johnson
On Friday, June 21, 2013 9:32:43 PM UTC-5, rusi wrote:
> So Rick... I agree with you... all these theoreticians
> should be burnt at the stake! On a more serious note: many
> people make similar mistakes eg Haskellers who think
> Haskell is safe. Safer (than something or other) -- Ok
> Safe -- NO

So now you're going to attempt to defeat my idea by
suggesting that it chalks up to nothing more than a safety
measure? How many times must i explain the simple concept
of stateless subroutines and hazards of the current 
incarnation Python FUNCtions (You smell the func!)

Yes you gain safety by utilizing such an implementation 
over the current implementation, however you also trim
a negative attribute of the language. Not to mention the
intuitive and readability gains.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: n00b question on spacing

2013-06-21 Thread Peter Otten
Yves S. Garret wrote:

> Hi, I have a question about breaking up really long lines of code in
> Python.
> 
> I have the following line of code:
> log.msg("Item wrote to MongoDB database %s/%s" %(settings['MONGODB_DB'],
> settings['MONGODB_COLLECTION']), level=log.DEBUG, spider=spider)
> 
> Given the fact that it goes off very far to the right on my screen is not
> terribly
> pleasing to my eyes (and can be rude for other developers).
> 
> I was thinking of splitting it up like so:
> log.msg("Item wrote to MongoDB database %s/%s"
>   %(settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
>   level=log.DEBUG, spider=spider)
> 
> Is this ok?  Are there any rules in Python when it comes to breaking up
> long lines of
> code?

You can move the goal posts and change your API (to one similar to the 
logging module in the standard library, for example):

log.debug(
"Wrote item to MongoDB database %s/%s",
settings["MONGODB_DB"],
settings["MONGODB_COLLECTIONS"],
spider=spider)

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


Re: Dealing with ' (suds)

2013-06-21 Thread dieter
Ombongi Moraa Fe  writes:

> I'm working with suds to send send messages to smsc. I've notices the
> messages with ' are really not processed on my side (which could mean
> an error occurs somewhere - most probably in my php script). SMSC has also
> asked that I 'take care of the '' as it's the reason my subscribers
> may not be receiving the responses.
>
> How can i 'take care of ' ' so it doesn't give me problems in future?

"'" is one of five so called entity references predefined
by the XML specification. The XML parser (that used by "suds")
should automatically convert it to "'". There should be no need
for your application to do anything special for "'".

Of course, there might be a bug somewhere (in "suds" or its parser).
A deeper analysis would be necessary to verify this assumption
and to locate/fix the bug. Even if this looks more difficult,
I recommend to go this route rather than to try something
special for "'" at the application level.

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


Re: Default Value

2013-06-21 Thread rusi
On Saturday, June 22, 2013 8:25:15 AM UTC+5:30, Rick Johnson wrote:
> On Friday, June 21, 2013 9:32:43 PM UTC-5, rusi wrote:
> > So Rick... I agree with you... all these theoreticians
> > should be burnt at the stake! 

> > On a more serious note: many
> > people make similar mistakes eg Haskellers who think
> > Haskell is safe. Safer (than something or other) -- Ok
> > Safe -- NO
> 
> 
> So now you're going to attempt to defeat my idea by
> suggesting that it chalks up to nothing more than a safety
> measure? How many times must i explain the simple concept
> of stateless subroutines and hazards of the current 
> incarnation Python FUNCtions (You smell the func!)

I appreciate Rick that you are committed to a better programming language.
And you too need to appreciate that many intelligent and capable people for the 
last 50 years have had similar goals.  When those goals are soft eg strictures 
on cohesion and coupling -- which is what your wish for stateless procedures 
amounts to -- then those remain suggestions and cannot be imposed.
When those goals are made hard as in functional programming then other problems 
result such as performance hits, what-to-do-about-IO etc etc.

See my blog
http://blog.languager.org/2012/11/imperative-programming-lessons-not.html
for a history of wishes akin to yours and lessons not learnt.

In short the problems accruing from unconstrained imperative programming are 
severe and the solutions are hard.

In the meanwhile, goals such as your 'keep-procedures-stateless' can and should 
certainly be practised in the human sphere even if not implemented in the 
programming language sphere.  The aggregation of such 'best-practices' is what 
I call FP as an ideology rather than as technology.
I have a collection here 
http://blog.languager.org/2012/10/functional-programming-lost-booty.html
And I would welcome suggestions/discussions on the same.
-- 
http://mail.python.org/mailman/listinfo/python-list