Re: Program prints questions for user input, but won't show the answer output

2016-05-18 Thread Larry Hudson via Python-list

On 05/18/2016 06:50 PM, Jake Kobs wrote:

MRAB,

I am not quite sure how to return the print statements so I thought that 
returning the displayInfo def would help.. Im so lost.

Why do you think you want to _return_ a print statement?  The print statement _DOES_ the 
printing, there is nothing that needs to be returned.  Sometimes you might want to return a 
_string_ to be printed where it was called from, but that's not what you want here.


You say that the display info isn't shown...  It looks to me like it it isn't shown because your 
program will crash.  What you have here is called "infinite recursion":


displayInfo() calls displayInfo() which calls displayInfo() which calls displayInfo() which 
calls ... and so on forever.


Another comment:  Your getHigh() and getLow() functions are not necessary.  Python already has 
max() and min() functions built in to do this exact same thing.  Instead you can use:


highPints = max(pints)
lowPints = min(pints)

Of course, writing your own versions as a leaning experience is good too.  But I would suggest 
that a for loop instead of a while in your version would be better.  For one thing, it 
eliminates the counter.  My suggested version...


def getHigh(pints):
high = 0
for pint in pints:
if pint > high:
high = pint
return high

And getLow() is similar (but set the initial value to a high number).

The following example may be more advanced than you're ready for now, but you _might_ find it 
worth studying.  It's possible to do both in a single function:


def getMaxMin(pints):
high = low = pints[0]#  Initialize high and low to the first value of 
the array
for pint in pints[1:]:   #  Scan through the remainder of the pints array
if pint > high:
high = pint
if pint < low:
low = pint
return high, low

You would use it as:

highPints, lowPints = getMaxMin(pints)

I'm NOT necessarily recommending this, but just suggesting it as an example to 
study.

Good luck with your Python studies.  It's a great language to learn.

 -=- Larry -=-

PS.  A final thought...

I don't know your situation so this may not be reasonable but...  I HIGHLY recommend switching 
to Python 3 instead of 2.  Version 2 is at "end-of-life" and won't be updated any further. 
Version 3 is where all future development will occur.  It is definitely the better version, and 
while there are certainly differences, to a beginning programmer the learning curve will be the 
same.


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


Re: Extract the middle N chars of a string

2016-05-18 Thread Wildman via Python-list
On Thu, 19 May 2016 01:47:33 +1000, Steven D'Aprano wrote:

> Is this the simplest way to get the middle N characters?

This will return a sub-string of any length starting at any
point.  This is the way the old VB mid$ function worked.

def mid(string, start, length):
# start begins at 0
if string = "":
return None
if start > len(string) - 1:
start = len(string) - 1
if length > len(string):
length = len(string)
if length < 1:
length = 1
return string[start : start + length]

-- 
 GNU/Linux user #557453
"The Constitution only gives people the right to
pursue happiness. You have to catch it yourself."
  -Benjamin Franklin
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Resources/pointers for writing maintable, testable Python

2016-05-18 Thread Rustom Mody
On Thursday, May 19, 2016 at 9:26:39 AM UTC+5:30, Steven D'Aprano wrote:
> On Thursday 19 May 2016 13:31, Rustom Mody wrote:
> 
> > On Thursday, May 19, 2016 at 6:26:26 AM UTC+5:30, Ben Finney wrote:
> 
> >> Code Like A Pythonista was written in the Python 2 era
> >> 
> >> but is still excellent advice today.
> > 
> > 
> > If  is python-2 and still the best excellent advice today
> > doesn't it go somewhat counter to pyhthon-2 is a dead-end ?? :-)
> 
> Ben didn't say that it is the *best* excellent advice.
> 
> But even if he did, your conclusion is invalid. I still have books written 
> for 
> Python 1.4 and 1.5 that I turn to when I can't remember % targets and regular 
> expression codes, and my copy of the Python Cookbook is still full of 
> excellent 
> code even though it is written for Python 2.

And you have the knowledge and experience to know that when you refer to
a python 2 (or 1) reference and apply it in 3 and there are minor glitches,
you know where to go for clarifications.

Maybe the OP also knows... maybe not...
No case against python3, just that the pro-3 rhetoric need not be so shrill

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


Re: Resources/pointers for writing maintable, testable Python

2016-05-18 Thread Steven D'Aprano
On Thursday 19 May 2016 13:31, Rustom Mody wrote:

> On Thursday, May 19, 2016 at 6:26:26 AM UTC+5:30, Ben Finney wrote:

>> Code Like A Pythonista was written in the Python 2 era
>> 
>> but is still excellent advice today.
> 
> 
> If  is python-2 and still the best excellent advice today
> doesn't it go somewhat counter to pyhthon-2 is a dead-end ?? :-)

Ben didn't say that it is the *best* excellent advice.

But even if he did, your conclusion is invalid. I still have books written for 
Python 1.4 and 1.5 that I turn to when I can't remember % targets and regular 
expression codes, and my copy of the Python Cookbook is still full of excellent 
code even though it is written for Python 2.


> Need to point this out since the opposite case to Chris'
> "switch to 3 or else suffer in hell..." needs to be articulated:
> 
> Python-3 is nice but 2 is ok. The diffs are not such a big deal

Python 2 is still an excellent language. It's just not going forward -- no new 
features will be added to it.


-- 
Steve

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


Re: Resources/pointers for writing maintable, testable Python

2016-05-18 Thread Chris Angelico
On Thu, May 19, 2016 at 1:31 PM, Rustom Mody  wrote:
> On Thursday, May 19, 2016 at 6:26:26 AM UTC+5:30, Ben Finney wrote:
>> Code Like A Pythonista was written in the Python 2 era
>> 
>> but is still excellent advice today.
>
>
> If  is python-2 and still the best excellent advice today
> doesn't it go somewhat counter to pyhthon-2 is a dead-end ?? :-)

Nope. Py2 is a dead end because it isn't moving forward. It's staying
right where it is. There can certainly be advice written about Python
2 that is worth reading, though. In fact, I have some books written
about REXX on OS/2 which I would recommend to someone learning Python
on Linux. I probably have some books from the 1980s that are still
worth reading. (Software books older than that won't be on my shelf,
but quite likely do exist.)

> Need to point this out since the opposite case to Chris'
> "switch to 3 or else suffer in hell..." needs to be articulated:

That is not my stance. Python 2 is still usable - it just isn't moving forward.

> Python-3 is nice but 2 is ok. The diffs are not such a big deal

The differences are getting to be a bigger and bigger deal. I wouldn't
advise anyone to use Python 2.4 unless compatibility with Red Hat
Enterprise Linux 5, because 2.4 misses out on heaps of stuff that
newer versions have. It's the same with 2.7 - use it if compatibility
with systems without 3.x is important, otherwise use the latest. (Of
course, that's new projects. Existing code implies a porting cost,
which has to be factored in; but making the jump to 3.5 or 3.6 is well
worth it IMO.)

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


Re: Resources/pointers for writing maintable, testable Python

2016-05-18 Thread Rustom Mody
On Thursday, May 19, 2016 at 6:26:26 AM UTC+5:30, Ben Finney wrote:
> Jacob Scott  writes:
> 
> > Today, I'm happily writing primarily Python (unfortunately, 2.7 -- but I'm
> > not sure it makes that much of a difference)
> 
> Python 2.7 is still viable, but is certainly a dead end. The difference
> increases month by month, and the advantage is only going to increase to
> Python 3.
> 
> Any new code base should not be written in Python 2. Any libraries you
> need which don't work yet on Python 3 should be seriously reconsidered.
> 
> > I'd appreciate any pointers to resources I might have missed, general
> > thoughts on the topic, etc.
> 
> Code Like A Pythonista was written in the Python 2 era
> 
> but is still excellent advice today.


If  is python-2 and still the best excellent advice today
doesn't it go somewhat counter to pyhthon-2 is a dead-end ?? :-) 


Need to point this out since the opposite case to Chris' 
"switch to 3 or else suffer in hell..." needs to be articulated:

Python-3 is nice but 2 is ok. The diffs are not such a big deal
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: setrecursionlimit

2016-05-18 Thread Rustom Mody
On Thursday, May 19, 2016 at 3:13:44 AM UTC+5:30, bream wrote:
> On Wednesday, May 18, 2016 at 6:47:42 PM UTC+1, Chris Kaynor wrote:
> > On Wed, May 18, 2016 at 10:15 AM, Steven D'Aprano wrote:
> > 
> > > I don't really understand why the system can't track the current top of 
> > > the
> > > stack and bottom of the heap, and if they're going to collide, halt the
> > > process. That would still be kinda awful, in a sudden "your application
> > > just died" kind of way, but it would be better than "your computer is now
> > > owned by some hacker in Hong Kong, who is now renting it by the hour to
> > > some spammer in Texas".
> > >
> > 
> > Most modern OSs will track it, and kill the app (hence the exception/crash
> > that occurs), rather than allow access outside the memory. 
> > Chris
> 
> Oh so funny, I just had to roar with laughter, unless you (plural) classify 
> VMS as a "modern OS".  Then of course some youngsters think the OS is simply 
> software, whereas us old gits know that a combination of hardware and 
> software makes for something that is rather more solid.

Hi Mark -- howdy!

Much truth in your comment.
Dijkstra pointed out (in mid-70s!) the essential tradeoff between hardware and
software. He did it for numeric oveflow but it applies equally for stack 
overflow.

In short software costs are variable costs: An instruction that is executed
a million times costs million-fold one that is executed only once.
For hardware its a fixed cost: Once the investment in silicon is done,
once or a billion times is the same.

Therefore -- and this is Dijkstra's key insight -- if a test is very skew,
ie if the if-part is 99.9% likely to be taken and the else part only 0.1%
the programmer will be increasingly tempted to drop the test and hope/pray that
the 0.1% does not happen.

With a hardware interrupt this temptation would be obviated.

Both the mess in catching numeric overflow as well as stackoverflow looks like
its C's fault. 
I consider it as the fault of currently fashionable stock hardware
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Resources/pointers for writing maintable, testable Python

2016-05-18 Thread Chris Angelico
On Thu, May 19, 2016 at 11:15 AM, Jacob Scott  wrote:
> I think I would be (perhaps pleasantly) surprised if there was a wide gulf
> between Python 2.7 and Python 3 *in terms of advice/resources applicable to
> my original question*. Based on my (admittedly shallow) understanding of
> overall Python 2.7/3 differences, the biggest changes (from e.g.
> http://sebastianraschka.com/Articles/2014_python_2_3_key_diff.html) tend to
> be a bit lower level (utf-8 str) than what I'm focused on (maintainable and
> testable classes, functions, modules, etc).

It's not really about UTF-8 (and the article you link to is flat wrong
in describing Py3's str type as UTF-8); it's about the recognition of
a fundamental difference between text and bytes. Looking at it another
way: Python 2 lets you pretend it's all easy, so long as you're
working with the simple Latin letters A-Z and a-z, but when you need
anything else (other alphabets, non-ASCII symbols like dashes and
quotes and emoji, diacritical marks, etc, etc), Python 2 doesn't help
you at all, and suddenly you're on your own. Python 3 forces you to
think up-front about things (a little bit of extra work/hassle), but
then gives you all the world's languages for free. That's a very high
level feature: you ask a user to enter his/her name, and instead of
requiring that it be English without diacritical marks, you can accept
(almost[1]) anything. Sometimes, UTF-8 lets you *pretend* that Python
2 (or C or PHP or whatever other language you pick) can handle all
those other characters too, but it's a massively leaky abstraction.

The other broad change in Python 3 is a shift in focus from concrete
lists to lazy objects. In Py2, range() returns a list of numbers; in
Py3, it returns a "range object", which functions just like that list
in many ways (subscripting, iterating, etc work the same way), but is
far more memory-efficient on huge ranges. In Py2, a dictionary's
keys() method returns a list; in Py3, it returns a special view
object. That kind of thing.

Quite a few of the other differences mentioned in that article are
actually the removal of already-deprecated syntax. For instance, the
'except NameError as err:' syntax works in 2.6 and 2.7 as well as 3.x,
and is the recommended way to spell it (unless you need to support
ancient Pythons - 2.5 is pretty old now, but some people do support
it). For backward compatibility, all of the 2.x line still supports
the old syntax, but new code should be using the reliable syntax - the
comma is ambiguous (what if you wanted to accept more than one
exception type?). Similarly, you shouldn't be calling an iterator's
.next() method directly; always call the built-in next() function.
Python 3 made this a lot clearer by renaming the method to __next__(),
which clarifies that this is a "magic method" or "special method.
Dunder methods are for defining, not calling. (Rule of thumb, not
entirely true, but close on.)

For the rest, Python 3 basically has the advantage of six additional
years of development time. That's given us features like exception
chaining, core support for virtual environments, a variety of new
stdlib modules, support for asynchronous I/O, a new multiplication
operator, and soon (3.6), interpolated string 'literals' (more like a
list comprehension than a string literal). And that gap is ever
widening. Using 2.7 means abandoning all those features. It's still in
support, but it's bug fixes and security patches only - which, as the
Red Queen explained to Alice, is where you have to run as fast as you
can just to stay in one place.

ChrisA

[1] Some people's names can't be represented in Unicode. But excluding
those names is a lot less significant than excluding the huge
proportion of people whose names aren't representable in ASCII.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Summing/combining tuples

2016-05-18 Thread Larry Hudson via Python-list

On 05/18/2016 05:59 PM, DFS wrote:

Have  aList = [
('x','Name1', 1, 85),
('x','Name2', 3, 219),
('x','Name2', 1, 21),
('x','Name3', 6, 169)
]

want

aList = [
('Name1', 1, 85),
('Name2', 4, 240),
('Name3', 6, 169)
]


This drops the first element in each tuple:
alist = [(b,c,d) for a,b,c,d in alist]


Slicing may be more efficient (perhaps, perhaps not -- don't know).  And probably effectively no 
difference, but slightly shorter to write.


alist = [t[1:] for t in alist]



And this summation creates 2 lists that then have to be combined:

groups1 = defaultdict(int)
for nm, matches, words in alist:
 groups1[nm] += matches

groups2 = defaultdict(int)
for nm, matches, words in alist:
 groups2[nm] += words



Is there something shorter and sweeter for the summation?

Thanks



Why two loops?  Put both summations in a single loop.  Then you're only scanning the alist once 
instead of twice.


groups1 = defaultdict(int)
groups2 = defaultdict(int)
for nm, matches, words in alist:
groups1[nm] += matches
groups2[nm] += words

 -=- Larry -=-

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


Re: Program prints questions for user input, but won't show the answer output

2016-05-18 Thread MRAB

On 2016-05-19 02:50, Jake Kobs wrote:

MRAB,

I am not quite sure how to return the print statements so I thought that 
returning the displayInfo def would help.. Im so lost.


"return the print statements"?

The print statements ... print!

Have a search for Python tutorials online and pick one that suits you.

I see that you're using Python 2. I'd suggest trying Python 3 unless you 
have a good reason for using Python 2.


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


Re: Program prints questions for user input, but won't show the answer output

2016-05-18 Thread Steven D'Aprano
On Thu, 19 May 2016 11:50 am, Jake Kobs wrote:

> MRAB,
> 
> I am not quite sure how to return the print statements so I thought that
> returning the displayInfo def would help.. Im so lost.

There's no need to return the text that you printed. You printed it, the job
is done.


Here is some general advice that may help you be less lost.

(1) Each function should do "one thing". For example, it either collects
information, or it displays it. It shouldn't do both. Your code seems
pretty good at following that guideline already, well done.

(2) Use existing functions as much as possible. The Python docs has a list
of the built-in functions here:

https://docs.python.org/2/library/functions.html

Refer to that as often as possible.

For example, your functions getHigh, getLow and getTotal functions just
re-invent the wheel. Python already has functions to do that:

max, min, sum

In Python 2, there's no built-in function for average, but for your purposes
you can just use sum(pints)/len(pints).

(3) Whoever taught you to write while loops should be taken out and
horse-whipped. While loops are for looping when you don't know in advance
how many times you need to repeat. When you do know how many times to
repeat, use a for-loop:

# I want to repeat seven times
for counter in range(7):
print "Loop", counter


Isn't that simpler than a while loop?

# I want to repeat seven times
counter = 7
while counter > 0:  # or should that be >= 0? >= 1? I forget!
print "Loop", counter
counter -= 1


And its faster too.


(4) Don't use "input". (The reasons are technical, if you really want to
know, please ask.) Instead of writing:

input("Enter pints collected: ")

write this:

int(raw_input("Enter pints collected: "))




-- 
Steven

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


Re: Program prints questions for user input, but won't show the answer output

2016-05-18 Thread Jake Kobs
MRAB,

I am not quite sure how to return the print statements so I thought that 
returning the displayInfo def would help.. Im so lost.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Extract the middle N chars of a string

2016-05-18 Thread Steven D'Aprano
On Thu, 19 May 2016 02:54 am, Peter Otten wrote:

> Peter Otten wrote:
> 
> def mid(s, n):
>> ... shave = len(s) - n
>> ... if shave > 0:
>   shave += len(s) % 2
>> ... shave //= 2
>> ... s = s[shave:shave+n]
>> ... return s
> 
>> Not exactly the same results as your implementation though.
> 
> The extra line should fix that, but it looks, err -- odd.

Nice! Thank you. I like this solution.



-- 
Steven

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


Re: Extract the middle N chars of a string

2016-05-18 Thread Steven D'Aprano
On Thu, 19 May 2016 03:00 am, MRAB wrote:

> I think your results are inconsistent.
> 
> For an odd number of characters you have "abc" + "de" + "fg", i.e. more
> on the left, but for an even number of characters you have "a" + "bcd" +
> "ef", i.e. more on the right.

Correct. That's intentional.

I didn't start with an algorithm. I started by manually extracting the N
middle characters, for various values of N, then wrote code to get the same
result.

For example, if I start with an odd-length string, like "inquisition", then
the "middle N" cases for odd-N are no-brainers, because they have to be
centered on the middle character:

N=1 's'
N=3 'isi'
N=5 'uisit'

For even-N, I had a choice:

N=2 'is' or 'si'

and to be perfectly frank, I didn't really care much either way and just
arbitrarily picked the second, based on the fact that string.center() ends
up with a slight bias to the right:

py> 'ab'.center(5, '*')
'**ab*'


For even-length string, like "aardvark", the even-N case is the no-brainer:

N=2 "dv"
N=4 "rdva"
N=6 "ardvar"

but with odd-N I have a choice:

N=3 "rdv" or "dva"

In this case, I *intentionally* biased it the other way, so that (in some
sense) overall the mid() function would be unbiased:

- half the cases, there's no bias at all;
- a quarter of the time, there's a bias to the right;
- a quarter of the time, there's a bias to the left;
- so on average, the bias is zero.


> My own solution is:
> 
> 
> def mid(string, n):
>  """Return middle n chars of string."""
>  if n <= 0:
>  return ''
>  if n > len(string):
>  return string
>  ofs = (len(string) - n) // 2
>  return string[ofs : ofs + n]
> 
> 
> If there's an odd number of characters remaining, it always has more on
> the right.


Thanks to you and Ian (who independently posted a similar solution), that's
quite good too if you don't care about the bias.



-- 
Steven

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


Re: Program prints questions for user input, but won't show the answer output

2016-05-18 Thread MRAB

On 2016-05-19 02:04, Jake Kobs wrote:

Here is the code:

#Lab 9-4 Blood Drive

#the main function
def main():
  endProgram = 'no'
  while endProgram == 'no':
print
# declare variables
pints = [0] * 7
totalPints = 0
averagePints = 0
highPints = 0
lowPints = 0












# function calls
pints = getPints(pints)
totalPints = getTotal(pints, totalPints)
averagePints = getAverage(totalPints, averagePints)
highPints = getHigh(pints, highPints)
lowPints = getLow(pints, lowPints)
displayInfo(averagePints, highPints, lowPints)

endProgram = raw_input('Do you want to end program? (Enter no or yes): ')
while not (endProgram == 'yes' or endProgram == 'no'):
  print 'Please enter a yes or no'
  endProgram = raw_input('Do you want to end program? (Enter no or yes): ')

#the getPints function
def getPints(pints):
counter = 0
while counter < 7:
pints[counter] = input("Enter pints collected: ")
counter = counter + 1
return pints
#the getTotal function
def getTotal(pints, totalPints):

counter = 0
while counter < 7:
totalPints = totalPints + pints[counter]
counter = counter + 1
return totalPints
#the getAverage function
def getAverage(totalPints, averagePints):
averagePints = totalPints / 7
return averagePints
#the getHigh function
def getHigh(pints, highPints):
highPints = pints[0]
counter = 1
while counter < 7:
if (pints[counter] > highPints):
highPints = pints[counter]


The indentation here is wrong:


counter = counter + 1


It will add 1 _only_ if pints[counter] > highPints.


return highPints
#the getLow function
def getLow(pints, lowPints):
lowPints = pints[0]
counter = 1
while counter < 7:
if (pints[counter] < lowPints):
lowPints = pints[counter]


The indentation here is wrong:


counter = counter + 1


It will add 1 _only_ if pints[counter] < highPints.


return lowPints
#the displayInfo function
def displayInfo(averagePints, highPints, lowPints):
print "The average pints donated was: ", averagePints
print "The highest amount of pints donated was: ", highPints
print "The lowest amount of pints donated was: ", lowPints


Why is 'displayInfo' calling itself here?


return displayInfo(averagePints, highPints, lowPints)

main()

The problem is that the display info isn't shown after the user types in their 
7 numerical values. Please help.



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


Re: Program prints questions for user input, but won't show the answer output

2016-05-18 Thread John Gordon
In <1cc14787-7061-45c9-a70e-1b16e3f5e...@googlegroups.com> Jake Kobs 
 writes:

> Here is the code:

> def getHigh(pints, highPints):
> highPints = pints[0]
> counter = 1
> while counter < 7:
> if (pints[counter] > highPints):
> highPints = pints[counter]
> counter = counter + 1
> return highPints

getHigh() goes into an infinite loop if pints[counter] is less than or
equal to highPints.


> def getLow(pints, lowPints):
> lowPints = pints[0]
> counter = 1
> while counter < 7:
> if (pints[counter] < lowPints):
> lowPints = pints[counter]
> counter = counter + 1
> return lowPints

And getLow() has a very similar problem.

I suspect you want to unindent the 'counter = counter + 1' statement
so that it is NOT inside the 'if' statement.

-- 
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"

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


Re: Resources/pointers for writing maintable, testable Python

2016-05-18 Thread Jacob Scott
Ah, what I should have done is note that I am writing Python 2.7 (and this
is at work, with all that entails...), but am happy to take advice that
applies only to Python 3 (even 3.5 or 3.6.0a1!) and work backwards to apply
it to Python 2.7.

I think I would be (perhaps pleasantly) surprised if there was a wide gulf
between Python 2.7 and Python 3 *in terms of advice/resources applicable to
my original question*. Based on my (admittedly shallow) understanding of
overall Python 2.7/3 differences, the biggest changes (from e.g.
http://sebastianraschka.com/Articles/2014_python_2_3_key_diff.html) tend to
be a bit lower level (utf-8 str) than what I'm focused on (maintainable and
testable classes, functions, modules, etc).

Thanks for the pointer to Code Like A Pythonista and the feedback on 2.7 vs
3!

Jacob

On Wed, May 18, 2016 at 5:55 PM, Ben Finney 
wrote:

> Jacob Scott  writes:
>
> > Today, I'm happily writing primarily Python (unfortunately, 2.7 -- but
> I'm
> > not sure it makes that much of a difference)
>
> Python 2.7 is still viable, but is certainly a dead end. The difference
> increases month by month, and the advantage is only going to increase to
> Python 3.
>
> Any new code base should not be written in Python 2. Any libraries you
> need which don't work yet on Python 3 should be seriously reconsidered.
>
> > I'd appreciate any pointers to resources I might have missed, general
> > thoughts on the topic, etc.
>
> Code Like A Pythonista was written in the Python 2 era
> 
> but is still excellent advice today.
>
> --
>  \ “I have the simplest tastes. I am always satisfied with the |
>   `\best.” —Oscar Wilde, quoted in _Chicago Brothers of the Book_, |
> _o__) 1917 |
> Ben Finney
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Extract the middle N chars of a string

2016-05-18 Thread Steven D'Aprano
On Thu, 19 May 2016 07:28 am, Random832 wrote:

> My take:
> 
> def mid(string, n):
> if n > len(string): n = len(string)
> if n <= 0: n = 0
> offset = int(len(string)/2+n/2)
> return string[offset:offset+n]
> 
> It doesn't get the same result as yours when the length is odd and N is
> even, but the problem is ambiguous there and I feel like my algorithm is
> more clear.

I'm not sure that "the algorithm is more clear" is the right way to judge
this. Especially when your function doesn't even come *close* to meeting
the requirements. It doesn't even return substrings of the right length!

py> for i in range(8):
... print mid('abcdefg', i)
...

e
ef
fg
fg
g
g

py> for i in range(7):
... print mid('abcdef', i)
...

d
ef
ef
f
f



I sympathise, I really do, because as my first post says, this really does
seem like it ought to be a no-brainer trivial exercise in slicing. Instead,
it is remarkably subtle and tricky to get right.




-- 
Steven

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


Program prints questions for user input, but won't show the answer output

2016-05-18 Thread Jake Kobs
Here is the code:

#Lab 9-4 Blood Drive

#the main function
def main():
  endProgram = 'no'
  while endProgram == 'no':
print 
# declare variables
pints = [0] * 7
totalPints = 0
averagePints = 0
highPints = 0
lowPints = 0






   





# function calls
pints = getPints(pints)
totalPints = getTotal(pints, totalPints)
averagePints = getAverage(totalPints, averagePints)
highPints = getHigh(pints, highPints)
lowPints = getLow(pints, lowPints)
displayInfo(averagePints, highPints, lowPints)
   
endProgram = raw_input('Do you want to end program? (Enter no or yes): ')
while not (endProgram == 'yes' or endProgram == 'no'):
  print 'Please enter a yes or no'
  endProgram = raw_input('Do you want to end program? (Enter no or yes): ')

#the getPints function
def getPints(pints):
counter = 0
while counter < 7: 
pints[counter] = input("Enter pints collected: ")
counter = counter + 1
return pints
#the getTotal function
def getTotal(pints, totalPints):

counter = 0
while counter < 7:
totalPints = totalPints + pints[counter]
counter = counter + 1
return totalPints
#the getAverage function
def getAverage(totalPints, averagePints):
averagePints = totalPints / 7
return averagePints
#the getHigh function
def getHigh(pints, highPints):
highPints = pints[0]
counter = 1
while counter < 7:
if (pints[counter] > highPints):
highPints = pints[counter]
counter = counter + 1
return highPints
#the getLow function
def getLow(pints, lowPints):
lowPints = pints[0]
counter = 1
while counter < 7:
if (pints[counter] < lowPints):
lowPints = pints[counter]
counter = counter + 1
return lowPints
#the displayInfo function
def displayInfo(averagePints, highPints, lowPints):
print "The average pints donated was: ", averagePints
print "The highest amount of pints donated was: ", highPints
print "The lowest amount of pints donated was: ", lowPints
return displayInfo(averagePints, highPints, lowPints)

main()

The problem is that the display info isn't shown after the user types in their 
7 numerical values. Please help.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Quote of the day

2016-05-18 Thread Ethan Furman

On 05/18/2016 05:43 PM, Steven D'Aprano wrote:

On Thu, 19 May 2016 09:30 am, Ethan Furman wrote:


On 05/18/2016 03:52 PM, Gregory Ewing wrote:

Ned Batchelder wrote:



I'm not sure how
the test runner could determine that it was empty.  I guess it could
introspect the test function to see if it had any real code in it,


Then people would just get clever at putting dummy code
in the test that fools the test runner but doesn't really
test anything...


Some would have, sure.

Either way, it's a solved issue now because we (finally ;) have the
@skip decorator.


That only solves the problem for responsible, decent developers.


Since I'm not a manager (and when I was, I wasn't the PHB type), 
responsible, decent developers are where I focus my attention.


--
~Ethan~

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


Re: Resources/pointers for writing maintable, testable Python

2016-05-18 Thread Ben Finney
Jacob Scott  writes:

> Today, I'm happily writing primarily Python (unfortunately, 2.7 -- but I'm
> not sure it makes that much of a difference)

Python 2.7 is still viable, but is certainly a dead end. The difference
increases month by month, and the advantage is only going to increase to
Python 3.

Any new code base should not be written in Python 2. Any libraries you
need which don't work yet on Python 3 should be seriously reconsidered.

> I'd appreciate any pointers to resources I might have missed, general
> thoughts on the topic, etc.

Code Like A Pythonista was written in the Python 2 era

but is still excellent advice today.

-- 
 \ “I have the simplest tastes. I am always satisfied with the |
  `\best.” —Oscar Wilde, quoted in _Chicago Brothers of the Book_, |
_o__) 1917 |
Ben Finney

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


Re: Extract the middle N chars of a string

2016-05-18 Thread Steven D'Aprano
On Thu, 19 May 2016 07:35 am, Grant Edwards wrote:

> On 2016-05-18, Steven D'Aprano  wrote:
> 
>> Getting the middle N seems like it ought to be easy:
> 
> I'm still trying to figure out when one would want to do that...

I wanted to centre some text and truncate it to a fixed width. So I needed
the middle N characters.



-- 
Steven

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


Re: Quote of the day

2016-05-18 Thread Steven D'Aprano
On Thu, 19 May 2016 09:30 am, Ethan Furman wrote:

> On 05/18/2016 03:52 PM, Gregory Ewing wrote:
>> Ned Batchelder wrote:
> 
>>> I'm not sure how
>>> the test runner could determine that it was empty.  I guess it could
>>> introspect the test function to see if it had any real code in it,
>>
>> Then people would just get clever at putting dummy code
>> in the test that fools the test runner but doesn't really
>> test anything...
> 
> Some would have, sure.
> 
> Either way, it's a solved issue now because we (finally ;) have the
> @skip decorator.

That only solves the problem for responsible, decent developers.

But I guarantee you that, right now, as we speak, there is some poor schmuck
out there whose Pointy Haired Boss has given him a Key Performance
Indicator of X tests passing (not failing or skipped) per week, and he's
responding by writing tests which pass by not testing anything.



-- 
Steven

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


Re: Basic Concepts

2016-05-18 Thread marcusjmurphy
On Wednesday, April 27, 2016 at 2:29:25 AM UTC-7, Smith wrote:
> Fill in the blanks to declare a variable, add 5 to it and print its value:
> 
>  >>> x = 4
>  >>> x_ = 5
>  >>> print_
> 
> 
> Any suggestion ?
> 
> Thanks

>>> x = 4
>>> x += 5
>>> print(x)
9
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Quote of the day

2016-05-18 Thread Ethan Furman

On 05/18/2016 03:52 PM, Gregory Ewing wrote:

Ned Batchelder wrote:



I'm not sure how
the test runner could determine that it was empty.  I guess it could
introspect the test function to see if it had any real code in it,


Then people would just get clever at putting dummy code
in the test that fools the test runner but doesn't really
test anything...


Some would have, sure.

Either way, it's a solved issue now because we (finally ;) have the 
@skip decorator.


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


Re: OT: limit number of connections from browser to my server?

2016-05-18 Thread Gregory Ewing

Grant Edwards wrote:

Product spec explicitly states HTTPS only.  I'm told that is not open
for discussion.  The customer is a large, somewhat bureaucratic German
corporation, and they generally mean it when they say something is
non-negotiable.


They're probably being sensible. The way the Internet of
Things is shaping up, it's far better to have too much
security than too little.

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


Re: Quote of the day

2016-05-18 Thread Gregory Ewing

Ned Batchelder wrote:

I'm not sure how
the test runner could determine that it was empty.  I guess it could
introspect the test function to see if it had any real code in it,


Then people would just get clever at putting dummy code
in the test that fools the test runner but doesn't really
test anything...

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


Re: Resources/pointers for writing maintable, testable Python

2016-05-18 Thread Andrew Farrell
Hi Jacob,

You are probably looking for the book Test-Driven Development with Python
.
You'll also want to look at py.test 

Cheers!
Andrew Farrell

On Wed, May 18, 2016 at 5:01 PM, Jacob Scott  wrote:

> Many years ago, when I was primarily writing Java, I found Misko
> Hevery's Guide:
> Writing Testable Code
> 
> to
> be incredibly helpful in guiding the design and structure of my codebase,
> and as reference for checking if my code was smelly.
>
> Today, I'm happily writing primarily Python (unfortunately, 2.7 -- but I'm
> not sure it makes that much of a difference), but I haven't found anything
> that speaks to me in the same way. Some of the best resources I've found,
> but which don't quite cover all of what I'm looking for, include
>
>- PEP-8 and PEP-20
>- The Hitchhiker's Guide to Python
>
>- Effective Python 
>
> I'd appreciate any pointers to resources I might have missed, general
> thoughts on the topic, etc.
>
> Thanks,
>
> Jacob
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Extract the middle N chars of a string

2016-05-18 Thread Grant Edwards
On 2016-05-18, Steven D'Aprano  wrote:

> Getting the middle N seems like it ought to be easy:

I'm still trying to figure out when one would want to do that...

-- 
Grant Edwards   grant.b.edwardsYow! My CODE of ETHICS
  at   is vacationing at famed
  gmail.comSCHROON LAKE in upstate
   New York!!

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


Re: Extract the middle N chars of a string

2016-05-18 Thread Random832
On Wed, May 18, 2016, at 11:47, Steven D'Aprano wrote:
> So after spending a ridiculous amount of time on what seemed like it
> ought
> to be a trivial function, and an embarrassingly large number of
> off-by-one
> and off-by-I-don't-even errors, I eventually came up with this:
> 
> def mid(string, n):
> """Return middle n chars of string."""
> L = len(string)
> if n <= 0:
> return ''
> elif n < L:
> Lr = L % 2
> a, ar = divmod(L-n, 2)
> b, br = divmod(L+n, 2)
> a += Lr*ar
> b += Lr*br
> string = string[a:b]
> return string

My take:

def mid(string, n):
if n > len(string): n = len(string)
if n <= 0: n = 0
offset = int(len(string)/2+n/2)
return string[offset:offset+n]

It doesn't get the same result as yours when the length is odd and N is
even, but the problem is ambiguous there and I feel like my algorithm is
more clear.

I'm funneling the special cases through the slice statement at the end
rather than simply returning string and '' because it's conceptually
nicer and because it could be used for other purposes than slicing
strings.
-- 
https://mail.python.org/mailman/listinfo/python-list


Resources/pointers for writing maintable, testable Python

2016-05-18 Thread Jacob Scott
Many years ago, when I was primarily writing Java, I found Misko
Hevery's Guide:
Writing Testable Code
 to
be incredibly helpful in guiding the design and structure of my codebase,
and as reference for checking if my code was smelly.

Today, I'm happily writing primarily Python (unfortunately, 2.7 -- but I'm
not sure it makes that much of a difference), but I haven't found anything
that speaks to me in the same way. Some of the best resources I've found,
but which don't quite cover all of what I'm looking for, include

   - PEP-8 and PEP-20
   - The Hitchhiker's Guide to Python
   
   - Effective Python 

I'd appreciate any pointers to resources I might have missed, general
thoughts on the topic, etc.

Thanks,

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


Re: OT: limit number of connections from browser to my server?

2016-05-18 Thread Grant Edwards
On 2016-05-16, Grant Edwards  wrote:

> Is there any way to limit the number of connections a browser uses to
> download a web page?

[Long-winded tail of woe...]

> So now I'm going to set up a simple Python HTTP server to try some
> other approaches:
>
>   1) Only allow the listening socket to accept 1 connection at a time.

That doesn't work.  If you refuse connections, at least one browser
(Chrome) fails some of the fetches and you end up sans css, js, png,
whatever.

>   2) Accept the TCP connection, but don't allow the SSL handshaking to
>  start on the "extra" connections.

That seems to work for Chrome (which seems to be the worst of the
lot).

If on the 2nd, 3rd, 4th, 5th connections you accept the TCP connection
and then stall before doing the SSL hadshake, Chrome stays happy _and_
will shift all fetches to the one connection who's handshake has
finished.  You probably can't depend on this behavior, but OTOH it
can't hurt.  However, since the web server is single-threaded, doing
this in practice ends up be rather complicated.

>   3) ???

I did find a bug in the glue between the SSL stack and the web server
that was causing (under certain conditions) an ssl-read operation to
block when it shouldn't.  Fixing that brought my cold page load time
down from 15 to 7-9 seconds.

The most promising approach is probably to minimize the number of
files by doing server-side includes for css, js, and image data.  If I
also add support for chunked transport, that should make a big
difference.  There are currently certain cases where the reply size
isn't known, so the connection can't be left open and re-used.  Each
time a connection has to be closed by ther server to indicate
endof-response, it's a big performance hit.  If the browser supported
chunked transport, it should allow all connections to be left open and
reused.  That would then makes a huge difference on subsequent page
load times as people work with the thing...

-- 
Grant Edwards   grant.b.edwardsYow! I'm having BEAUTIFUL
  at   THOUGHTS about the INSIPID
  gmail.comWIVES of smug and wealthy
   CORPORATE LAWYERS ...

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


Re: setrecursionlimit

2016-05-18 Thread Christian Gollwitzer

Am 18.05.16 um 19:15 schrieb Steven D'Aprano:

Not being a C programmer, I don't really understand this.

The idea I have in mind is a model of program memory I learned[1] way back
in the 80s. I don't know if it's still valid. Your application has a bunch
of memory available, which broadly speaking can be divided into three
chunks: globals, the stack, and the heap.

The application knows what globals exist, and can allocate a fixed block of
memory big enough for them, so that's not very interesting. It just sits
there, holding space for the globals, and doesn't grow or shrink.

Then there's the stack, which holds local variables whenever a function is
called, the return address of the caller, and other stuff. There's a fixed
bottom to the stack, but the top can grown and shrink depending on how many
functions you call and how many local variables they use.


Until here, it is reasonably accurate. On some machines, the stack does 
grow in the other direction, but that does not matter either. ON x86, it 
grows from top to bottom



Then there's everything else, which is the heap, and it can grown and shrink
in both directions (up to some maximum, of course):

bottom [ globals | stack ->  <- heap -> ] top

If the stack grows into the heap, or vice versa, Bad Things happen. At best
you get a crash. At worst you get arbitrary code execution.


No, you have virtual memory management in effect in the OS which maps 
the real memory addresses into your address space. On 64 bit, a 
collision between stack and heap is practically impossible.



I don't really understand why the system can't track the current top of the
stack and bottom of the heap, and if they're going to collide, halt the
process.


It does. But in a different way. For the heap, you need to call a 
function which asks for more memory. It returns an error code, if the 
memory can't be supplied. The problem is that often in this case, the 
program needs more memory to handle that, e.g. to format an error 
message. If you allocate memory in small pieces until it is exhausted, 
the program will die in unforeseen ways. If you try to alloc 1TB on the 
heap and it fails, there is enough room for a clean shutdown. Unless the 
C program is buggy and does not check the error.


On the stack, you don't allocate by telling the OS. You simply increase 
the stack pointer register. This is a single machine instruction, very 
fast, and unfeasible to trap by the OS and intercept. Instead, the stack 
is framed by pages which are non-writeable. As soon as the program tries 
to write there, it segfaults (SIGSEGV or SIGBUS). At this point there is 
no way to cleanly exit the program, therefore you see the 
crash/segfault. It might happen that you overrun the stack so much as to 
reach writeable memory again. But not under normal circumstances, where 
only a few bytes are pushed/popped.



That would still be kinda awful, in a sudden "your application
just died" kind of way, but it would be better than "your computer is now
owned by some hacker in Hong Kong, who is now renting it by the hour to
some spammer in Texas".


Stack overflow does not usually lead to security risks. A buffer 
overflow is different: It means that the program allocates a fixed-size 
buffer on the stack, which overflows and writes into the return 
addresses / local variables of functions higher up the callchain. The 
basic problem here is, that the C programmer was too lazy to get the 
memory from the heap.


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


Re: setrecursionlimit

2016-05-18 Thread Chris Kaynor
On Wed, May 18, 2016 at 10:15 AM, Steven D'Aprano 
wrote:

> I don't really understand why the system can't track the current top of the
> stack and bottom of the heap, and if they're going to collide, halt the
> process. That would still be kinda awful, in a sudden "your application
> just died" kind of way, but it would be better than "your computer is now
> owned by some hacker in Hong Kong, who is now renting it by the hour to
> some spammer in Texas".
>

Most modern OSs will track it, and kill the app (hence the exception/crash
that occurs), rather than allow access outside the memory.

What generally happens is that, when a thread is created (including the
main thread during startup), the OS will allocate enough pages to hold the
requested stack, plus one as a buffer. Most of these are virtual pages,
with no backing memory allocated (either in RAM or the page file). When the
next page is first requested, the OS will actually allocate the RAM needed
for that page of the stack. If the final guard page is hit, the OS will
throw an exception, which generally kills the app. This means there is a
overhead when a previously unused stack page is hit, however, as this
generally does not happen often, it is generally acceptable.

I cannot quickly find the reference material I learned this from, and
naturally it will vary based on the OS, however this is pretty standard for
general purpose, modern OSes.

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


Re: setrecursionlimit

2016-05-18 Thread Ian Kelly
On Wed, May 18, 2016 at 11:15 AM, Steven D'Aprano  wrote:
> I don't really understand why the system can't track the current top of the
> stack and bottom of the heap, and if they're going to collide, halt the
> process. That would still be kinda awful, in a sudden "your application
> just died" kind of way, but it would be better than "your computer is now
> owned by some hacker in Hong Kong, who is now renting it by the hour to
> some spammer in Texas".

Seems kind of expensive for little benefit to have to make that check
on every function call.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: setrecursionlimit

2016-05-18 Thread Steven D'Aprano
On Thu, 19 May 2016 02:29 am, Rob Gaddi wrote:

> Ned Batchelder wrote:

>> Is there a way to know how large the C stack can grow, and how much it
>> will grow for each Python function call? That sounds complicated to get
>> right.
>>
>> --Ned.
> 
> It's probably trivial to look at a number and say "Yeah, no, that's
> CLEARLY too high." based on the minimum number of bytes a stack frame
> can require. Guaranteeing that some number lower than that is safe is
> almost certainly impossible. So you'd get an exception for truly
> stupid numbers, but a lack of exception is no guarantee of safety.
> Which is worth what it's worth, I guess.

Not being a C programmer, I don't really understand this.

The idea I have in mind is a model of program memory I learned[1] way back
in the 80s. I don't know if it's still valid. Your application has a bunch
of memory available, which broadly speaking can be divided into three
chunks: globals, the stack, and the heap.

The application knows what globals exist, and can allocate a fixed block of
memory big enough for them, so that's not very interesting. It just sits
there, holding space for the globals, and doesn't grow or shrink.

Then there's the stack, which holds local variables whenever a function is
called, the return address of the caller, and other stuff. There's a fixed
bottom to the stack, but the top can grown and shrink depending on how many
functions you call and how many local variables they use.

Then there's everything else, which is the heap, and it can grown and shrink
in both directions (up to some maximum, of course):

bottom [ globals | stack ->  <- heap -> ] top

If the stack grows into the heap, or vice versa, Bad Things happen. At best
you get a crash. At worst you get arbitrary code execution.


I don't really understand why the system can't track the current top of the
stack and bottom of the heap, and if they're going to collide, halt the
process. That would still be kinda awful, in a sudden "your application
just died" kind of way, but it would be better than "your computer is now
owned by some hacker in Hong Kong, who is now renting it by the hour to
some spammer in Texas".



[1] I say "learned", but in reality I more sort of absorbed it by osmosis.
Nobody ever actually sat down and told me how the stack and heap work, so
the model I have might be completely wrong, even for 1980s tech.


-- 
Steven

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


Re: Extract the middle N chars of a string

2016-05-18 Thread MRAB

On 2016-05-18 16:47, Steven D'Aprano wrote:

Extracting the first N or last N characters of a string is easy with
slicing:

s[:N]  # first N
s[-N:]  # last N

Getting the middle N seems like it ought to be easy:

s[N//2:-N//2]

but that is wrong. It's not even the right length!

py> s = 'aardvark'
py> s[5//2:-5//2]
'rdv'


So after spending a ridiculous amount of time on what seemed like it ought
to be a trivial function, and an embarrassingly large number of off-by-one
and off-by-I-don't-even errors, I eventually came up with this:

def mid(string, n):
"""Return middle n chars of string."""
L = len(string)
if n <= 0:
return ''
elif n < L:
Lr = L % 2
a, ar = divmod(L-n, 2)
b, br = divmod(L+n, 2)
a += Lr*ar
b += Lr*br
string = string[a:b]
return string


which works for me:


# string with odd number of characters
py> for i in range(1, 8):
... print mid('abcdefg', i)
...
d
de
cde
cdef
bcdef
bcdefg
abcdefg
# string with even number of characters
py> for i in range(1, 7):
... print mid('abcdef', i)
...
c
cd
bcd
bcde
abcde
abcdef



Is this the simplest way to get the middle N characters?


I think your results are inconsistent.

For an odd number of characters you have "abc" + "de" + "fg", i.e. more 
on the left, but for an even number of characters you have "a" + "bcd" + 
"ef", i.e. more on the right.



My own solution is:


def mid(string, n):
"""Return middle n chars of string."""
if n <= 0:
return ''

if n > len(string):
return string

ofs = (len(string) - n) // 2

return string[ofs : ofs + n]


If there's an odd number of characters remaining, it always has more on 
the right.


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


Re: setrecursionlimit

2016-05-18 Thread Chris Kaynor
On Wed, May 18, 2016 at 9:19 AM, Ned Batchelder 
wrote:

> I believe the issue here is that Python recursion results in the C stack
> growing.  Each Python function call creates a number of C function calls,
> which grows the C stack.  The crash you see is the C stack overflowing.
>
> Is there a way to know how large the C stack can grow, and how much it
> will grow for each Python function call? That sounds complicated to get
> right.
>

I'm fairly sure that it is, in fact, basically impossible to get right.

Some Python calls will use more memory on the C stack than others. They may
call more C functions internally, or C functions that require more stack
space. In the most extreme example, you could have a single Python call
crash (for example, having a super deeply recursive call as a single Python
call), or you could theoretically have extremely deep Python recursion
without a problem (presuming optimizations that do not exist in CPython for
a number of, generally good, reasons).

Even in more typical cases, I believe a Python call with keyword arguments
requires more stack than one with only positional arguments, which may
require more than one with no arguments (depending on which CPython APIs
were used). Additionally, even within the standard library, some of the
native calls will require more stack (think OS calls) than most of the
basic math functions and simple operators (like int add).

The root of the issue is that, much of the time, C function arguments are
allocated on the stack, if they exceed certain limits based on the calling
convention used. 32-bit Windows only allocates the "this" pointer as a
register, all other arguments are stack [1]. 64-bit Windows allocates up-to
4 word arguments as registers, and the rest on the stack [2]. I do not know
what the Linux conventions are. Naturally, these rules may vary based on
the compiler, for any functions the compiler knows is being compiled by the
compiler - the rules listed for the OS are only required for OS calls,
however most compilers will follow them for ease. Additionally, any local
variables that do not fit in registers will be offloaded to the stack, and
sometimes they will be offloaded even if they do fit, at the compiler's
decision, especially if function calls are made.

All of this means that, as Ned mentioned, it is very complicated to figure
out a *recursion* depth that will cause a stack overflow. Generally, there
will be an OS method to determine the stack size in *bytes*, however (and
often, the application can control this when creating threads and in
executable meta data for the main thread). There is basically no way to
convert that bytes to a recursion level, however - the best you can do is
as Rob said, see that a depth is obviously higher than valid, as it is a
reasonable (but not guaranteed) guess that each recusion will use some
number of bytes of stack.

[1] https://msdn.microsoft.com/en-us/library/984x0h58.aspx
[2] https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx

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


Re: Extract the middle N chars of a string

2016-05-18 Thread Peter Otten
Peter Otten wrote:

 def mid(s, n):
> ... shave = len(s) - n
> ... if shave > 0:
  shave += len(s) % 2
> ... shave //= 2
> ... s = s[shave:shave+n]
> ... return s

> Not exactly the same results as your implementation though.

The extra line should fix that, but it looks, err -- odd.

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


Re: Quote of the day

2016-05-18 Thread Steven D'Aprano
On Thu, 19 May 2016 02:05 am, Ethan Furman wrote:

> On 05/18/2016 08:35 AM, Thomas Mlynarczyk wrote:
>> On 18/05/16 17:21, Ned Batchelder wrote:
> 
>>> Ideally, an empty test wouldn't be a success, but I'm not sure how
>>> the test runner could determine that it was empty.  I guess it could
>>> introspect the test function to see if it had any real code in it,
>>> but I don't know of a test runner that does that.
>>
>> Simple: a function which does not produce at least one "failure" or
>> "pass" does not test anything. No need to introspect the code. Just
>> check if the total score of failures and passes has changed after the
>> function was run.

I think you have misunderstood how unittest currently works. A do-nothing
test already counts as a pass. Here's a dumb test which is pointless,
followed by an even dumber one that does literally nothing:


[steve@ando ~]$ cat dumbtest.py
import unittest

class MyTest(unittest.TestCase):
def test_something(self):
self.assertEqual(100, 100.0)
def test_nothing(self):
pass


And now watch as both the pointless and the do-nothing tests count as
passed:


[steve@ando ~]$ python -m unittest --verbose dumbtest
test_nothing (dumbtest.MyTest) ... ok
test_something (dumbtest.MyTest) ... ok

--
Ran 2 tests in 0.001s

OK



So to start with, for your solution to be workable, we'd have to change the
way unittest decides what is a success and what isn't.

 
> Not so simple: I have tests that do nothing besides build objects.  If
> building the objects raises no errors the test passed.

It wouldn't be hard to add a "success" method to unittest, so that after
building the object you just call self.success() to flag it as passing.

But now the obvious way to have fake unittests is:

def test_nothing(self):
self.success()


The problem here is not a technical problem. It is a cultural or human
problem: somebody, due to malice, incompetence, overwork, ignorance or
stupidity, wrote a fake test that didn't actually test anything. Maybe
their intentions were good, and they meant for it to do something and it
just got forgotten... or maybe they deliberately thought that they could
satisfy the letter of the requirement "must have unit tests" without
putting in the hard work to satisfy the spirit of it.

Either way, until the testing framework contains enough artificial
intelligence to actually reason about whether the test is *useful* or not,
there's no technological way to solve this problem. You need a person[1]
intelligent enough to make a judgement "wait a minute, this code doesn't
test anything useful".

And that's a hard problem. Even human beings do poorly at that. The idea
that the test framework could solve it is naive.


> Although, for the benefit of empty tests not passing I could add a
> do-nothing assert:
> 
>self.assertTrue(created_obj)
> 
> (it's a do-nothing because if the object wasn't created the test would
> have already failed).

It wouldn't have failed. It would have raised an exception, which is
different. (Curse you English, we need more words for describing kinds of
failure!!!)

unittest supports four different test results:

- pass
- fail
- error (raise an exception)
- skip

which print as . F E S respectively. The tests you're describing will print
as E rather than F, which is better than a failure. A test failure is code
that silently does the wrong thing:

"I find it amusing when novice programmers believe their
 main job is preventing programs from crashing. ... More
 experienced programmers realize that correct code is
 great, code that crashes could use improvement, but
 incorrect code that doesn’t crash is a horrible nightmare."
 -- Chris Smith

while an E means that your code will cleverly raise an exception instead of
doing the wrong thing :-)






[1] Human or machine person, I don't care.


-- 
Steven

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


Re: Extract the middle N chars of a string

2016-05-18 Thread Peter Otten
Steven D'Aprano wrote:

> Extracting the first N or last N characters of a string is easy with
> slicing:
> 
> s[:N]  # first N
> s[-N:]  # last N
> 
> Getting the middle N seems like it ought to be easy:
> 
> s[N//2:-N//2]
> 
> but that is wrong. It's not even the right length!
> 
> py> s = 'aardvark'
> py> s[5//2:-5//2]
> 'rdv'
> 
> 
> So after spending a ridiculous amount of time on what seemed like it ought
> to be a trivial function, and an embarrassingly large number of off-by-one
> and off-by-I-don't-even errors, I eventually came up with this:
> 
> def mid(string, n):
> """Return middle n chars of string."""
> L = len(string)
> if n <= 0:
> return ''
> elif n < L:
> Lr = L % 2
> a, ar = divmod(L-n, 2)
> b, br = divmod(L+n, 2)
> a += Lr*ar
> b += Lr*br
> string = string[a:b]
> return string
> 
> 
> which works for me:
> 
> 
> # string with odd number of characters
> py> for i in range(1, 8):
> ... print mid('abcdefg', i)
> ...
> d
> de
> cde
> cdef
> bcdef
> bcdefg
> abcdefg
> # string with even number of characters
> py> for i in range(1, 7):
> ... print mid('abcdef', i)
> ...
> c
> cd
> bcd
> bcde
> abcde
> abcdef
> 
> 
> 
> Is this the simplest way to get the middle N characters?

>>> def mid(s, n):
... shave = len(s) - n
... if shave > 0:
... shave //= 2
... s = s[shave:shave+n]
... return s
... 
>>> def show(s):
... for i in range(len(s)+1):
... print(i, repr(s), "-->", repr(mid(s, i)))
... 
>>> show("abcdefg")
0 'abcdefg' --> ''
1 'abcdefg' --> 'd'
2 'abcdefg' --> 'cd'
3 'abcdefg' --> 'cde'
4 'abcdefg' --> 'bcde'
5 'abcdefg' --> 'bcdef'
6 'abcdefg' --> 'abcdef'
7 'abcdefg' --> 'abcdefg'
>>> show("abcdef")
0 'abcdef' --> ''
1 'abcdef' --> 'c'
2 'abcdef' --> 'cd'
3 'abcdef' --> 'bcd'
4 'abcdef' --> 'bcde'
5 'abcdef' --> 'abcde'
6 'abcdef' --> 'abcdef'

Not exactly the same results as your implementation though.

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


Re: Extract the middle N chars of a string

2016-05-18 Thread Ian Kelly
On Wed, May 18, 2016 at 9:47 AM, Steven D'Aprano  wrote:
> Extracting the first N or last N characters of a string is easy with
> slicing:
>
> s[:N]  # first N
> s[-N:]  # last N
>
> Getting the middle N seems like it ought to be easy:
>
> s[N//2:-N//2]
>
> but that is wrong. It's not even the right length!
>
> py> s = 'aardvark'
> py> s[5//2:-5//2]
> 'rdv'
>
>
> So after spending a ridiculous amount of time on what seemed like it ought
> to be a trivial function, and an embarrassingly large number of off-by-one
> and off-by-I-don't-even errors, I eventually came up with this:
>
> def mid(string, n):
> """Return middle n chars of string."""
> L = len(string)
> if n <= 0:
> return ''
> elif n < L:
> Lr = L % 2
> a, ar = divmod(L-n, 2)
> b, br = divmod(L+n, 2)
> a += Lr*ar
> b += Lr*br
> string = string[a:b]
> return string
>
>
> which works for me:
>
>
> # string with odd number of characters
> py> for i in range(1, 8):
> ... print mid('abcdefg', i)
> ...
> d
> de
> cde
> cdef
> bcdef
> bcdefg
> abcdefg
> # string with even number of characters
> py> for i in range(1, 7):
> ... print mid('abcdef', i)
> ...
> c
> cd
> bcd
> bcde
> abcde
> abcdef
>
>
>
> Is this the simplest way to get the middle N characters?

There's an ambiguity in the problem description when N and the length
of the string have different parity, but how about:

def mid(string, n):
L = len(string)
a = (L - n) // 2
return string[a:a+n]

py> for i in range(1, 8):
... print(mid('abcdefg', i))
...
d
cd
cde
bcde
bcdef
abcdef
abcdefg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: setrecursionlimit

2016-05-18 Thread Rob Gaddi
Ned Batchelder wrote:

> On Wednesday, May 18, 2016 at 12:11:25 PM UTC-4, Steven D'Aprano wrote:
>> The documentation for setrecursion limit warns against setting the limit too
>> high:
>> 
>> [quote]
>> The highest possible limit is platform-dependent. A user may need to
>> set the limit higher when they have a program that requires deep
>> recursion and a platform that supports a higher limit. This should
>> be done with care, because a too-high limit can lead to a crash.
>> [end quote]
>> 
>> https://docs.python.org/3/library/sys.html#sys.setrecursionlimit
>> 
>> Indeed, if you set the recursion limit too high, you can smash the memory
>> heap and get a segfault. How exactly does that work?
>> 
>> Why doesn't setrecursionlimit() raise an exception when you try to set it
>> too high? For example:
>> 
>> sys.setrecursionlimit(20)
>> 
>> succeeds on my system, even though that's a ludicrously high number. (It is
>> more than half the number of bytes of memory my computer has.)
>> 
>> 
>> So why can't Python tell if I'm setting the limit too high?
>> 
>> (I'm assuming that if it could, it would.)
>
> I believe the issue here is that Python recursion results in the C stack
> growing.  Each Python function call creates a number of C function calls,
> which grows the C stack.  The crash you see is the C stack overflowing.
>
> Is there a way to know how large the C stack can grow, and how much it
> will grow for each Python function call? That sounds complicated to get
> right.
>
> --Ned.

It's probably trivial to look at a number and say "Yeah, no, that's
CLEARLY too high." based on the minimum number of bytes a stack frame
can require. Guaranteeing that some number lower than that is safe is
almost certainly impossible. So you'd get an exception for truly
stupid numbers, but a lack of exception is no guarantee of safety.
Which is worth what it's worth, I guess.

-- 
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order.  See above to fix.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: setrecursionlimit

2016-05-18 Thread Ned Batchelder
On Wednesday, May 18, 2016 at 12:11:25 PM UTC-4, Steven D'Aprano wrote:
> The documentation for setrecursion limit warns against setting the limit too
> high:
> 
> [quote]
> The highest possible limit is platform-dependent. A user may need to
> set the limit higher when they have a program that requires deep
> recursion and a platform that supports a higher limit. This should
> be done with care, because a too-high limit can lead to a crash.
> [end quote]
> 
> https://docs.python.org/3/library/sys.html#sys.setrecursionlimit
> 
> Indeed, if you set the recursion limit too high, you can smash the memory
> heap and get a segfault. How exactly does that work?
> 
> Why doesn't setrecursionlimit() raise an exception when you try to set it
> too high? For example:
> 
> sys.setrecursionlimit(20)
> 
> succeeds on my system, even though that's a ludicrously high number. (It is
> more than half the number of bytes of memory my computer has.)
> 
> 
> So why can't Python tell if I'm setting the limit too high?
> 
> (I'm assuming that if it could, it would.)

I believe the issue here is that Python recursion results in the C stack
growing.  Each Python function call creates a number of C function calls,
which grows the C stack.  The crash you see is the C stack overflowing.

Is there a way to know how large the C stack can grow, and how much it
will grow for each Python function call? That sounds complicated to get
right.

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


setrecursionlimit

2016-05-18 Thread Steven D'Aprano
The documentation for setrecursion limit warns against setting the limit too
high:

[quote]
The highest possible limit is platform-dependent. A user may need to
set the limit higher when they have a program that requires deep
recursion and a platform that supports a higher limit. This should
be done with care, because a too-high limit can lead to a crash.
[end quote]

https://docs.python.org/3/library/sys.html#sys.setrecursionlimit

Indeed, if you set the recursion limit too high, you can smash the memory
heap and get a segfault. How exactly does that work?

Why doesn't setrecursionlimit() raise an exception when you try to set it
too high? For example:

sys.setrecursionlimit(20)

succeeds on my system, even though that's a ludicrously high number. (It is
more than half the number of bytes of memory my computer has.)


So why can't Python tell if I'm setting the limit too high?

(I'm assuming that if it could, it would.)




-- 
Steven

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


Re: Quote of the day

2016-05-18 Thread Ethan Furman

On 05/18/2016 08:35 AM, Thomas Mlynarczyk wrote:

On 18/05/16 17:21, Ned Batchelder wrote:



Ideally, an empty test wouldn't be a success, but I'm not sure how
the test runner could determine that it was empty.  I guess it could
introspect the test function to see if it had any real code in it,
but I don't know of a test runner that does that.


Simple: a function which does not produce at least one "failure" or
"pass" does not test anything. No need to introspect the code. Just
check if the total score of failures and passes has changed after the
function was run.


Not so simple: I have tests that do nothing besides build objects.  If 
building the objects raises no errors the test passed.


Although, for the benefit of empty tests not passing I could add a 
do-nothing assert:


  self.assertTrue(created_obj)

(it's a do-nothing because if the object wasn't created the test would 
have already failed).


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


Re: Quote of the day

2016-05-18 Thread Ned Batchelder
On Wednesday, May 18, 2016 at 11:36:03 AM UTC-4, Thomas Mlynarczyk wrote:
> On 18/05/16 17:21, Ned Batchelder wrote:
> > Ideally, an empty test wouldn't be a success, but I'm not sure how
> > the test runner could determine that it was empty.  I guess it could
> > introspect the test function to see if it had any real code in it,
> > but I don't know of a test runner that does that.
> 
> Simple: a function which does not produce at least one "failure" or
> "pass" does not test anything. No need to introspect the code. Just
> check if the total score of failures and passes has changed after the
> function was run.

For test frameworks that use explicit assertion methods (unittest has
self.assertEqual, for example), that could work.  I'm not sure whether
py.test and the other "bare assert" frameworks have the instrumentation
to make that possible.

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


Extract the middle N chars of a string

2016-05-18 Thread Steven D'Aprano
Extracting the first N or last N characters of a string is easy with
slicing:

s[:N]  # first N
s[-N:]  # last N

Getting the middle N seems like it ought to be easy:

s[N//2:-N//2]

but that is wrong. It's not even the right length!

py> s = 'aardvark'
py> s[5//2:-5//2]
'rdv'


So after spending a ridiculous amount of time on what seemed like it ought
to be a trivial function, and an embarrassingly large number of off-by-one
and off-by-I-don't-even errors, I eventually came up with this:

def mid(string, n):
"""Return middle n chars of string."""
L = len(string)
if n <= 0:
return ''
elif n < L:
Lr = L % 2
a, ar = divmod(L-n, 2)
b, br = divmod(L+n, 2)
a += Lr*ar
b += Lr*br
string = string[a:b]
return string


which works for me:


# string with odd number of characters
py> for i in range(1, 8):
... print mid('abcdefg', i)
...
d
de
cde
cdef
bcdef
bcdefg
abcdefg
# string with even number of characters
py> for i in range(1, 7):
... print mid('abcdef', i)
...
c
cd
bcd
bcde
abcde
abcdef



Is this the simplest way to get the middle N characters?



-- 
Steven

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


Re: Quote of the day

2016-05-18 Thread Thomas Mlynarczyk
On 18/05/16 17:21, Ned Batchelder wrote:
> Ideally, an empty test wouldn't be a success, but I'm not sure how
> the test runner could determine that it was empty.  I guess it could
> introspect the test function to see if it had any real code in it,
> but I don't know of a test runner that does that.

Simple: a function which does not produce at least one "failure" or
"pass" does not test anything. No need to introspect the code. Just
check if the total score of failures and passes has changed after the
function was run.

Thomas

-- 
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Quote of the day

2016-05-18 Thread Ned Batchelder
On Wednesday, May 18, 2016 at 8:06:11 AM UTC-4, Thomas Mlynarczyk wrote:
> On 17/05/16 12:39, Cem Karan wrote:
> > Just downloaded and used a library that came with unit tests, which all 
> > passed.
> > [...]
> > I discovered they had commented out the bodies of some of the unit
> tests...
> 
> Shouldn't the unit test framework have those "empty" tests reported as
> "todo"/"incomplete" or whatever? (I know that PHPUnit reports such tests
> as "passed" which I find utterly wrong.)

The xUnit pattern is that if a test runs without an error or a failed
assertion, then the test passes.  An empty test function that does
nothing will meet this criterion, so it passes.

Ideally, an empty test wouldn't be a success, but I'm not sure how
the test runner could determine that it was empty.  I guess it could
introspect the test function to see if it had any real code in it,
but I don't know of a test runner that does that.

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


Re: OT: limit number of connections from browser to my server?

2016-05-18 Thread Grant Edwards
On 2016-05-17, Dennis Lee Bieber  wrote:
> On Tue, 17 May 2016 18:42:12 + (UTC), Grant Edwards
> declaimed the following:
>
>
>>40MHz with multiple MB of RAM is pretty high-end in my book.  I've
>
>   How about a 68040 running at 30MHz (when not running in a dual system
> with a 20MHz board) 

The '040 even supports hardware floating point and virtual memory (and
it has I/D cache). That's livin' large!  We've got brand-new products
coming out later this year without all that fancy stuff.

-- 
Grant Edwards   grant.b.edwardsYow! I haven't been married
  at   in over six years, but we
  gmail.comhad sexual counseling every
   day from Oral Roberts!!

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


Re: Quote of the day

2016-05-18 Thread Chris Angelico
On Wed, May 18, 2016 at 10:05 PM, Thomas Mlynarczyk
 wrote:
> On 17/05/16 12:39, Cem Karan wrote:
>> Just downloaded and used a library that came with unit tests, which all 
>> passed.
>> [...]
>> I discovered they had commented out the bodies of some of the unit
> tests...
>
> Shouldn't the unit test framework have those "empty" tests reported as
> "todo"/"incomplete" or whatever? (I know that PHPUnit reports such tests
> as "passed" which I find utterly wrong.)

In Python, the unittest framework allows you to 'skip' tests for any
reason. That would be the best.

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


Re: OrderedDict

2016-05-18 Thread Peter Otten
Chris Angelico wrote:

> On Wed, May 18, 2016 at 7:28 PM, Peter Otten <__pete...@web.de> wrote:
>> I don't see an official way to pass a custom dict type to the library,
>> but if you are not afraid to change its source code the following patch
>> will allow you to access the value of dictionaries with a single entry as
>> d[0]:
>>
>> $ diff -u py2b_xmltodict/local/lib/python2.7/site-packages/xmltodict.py
>> py2_xmltodict/local/lib/python2.7/site-packages/xmltodict.py
>> --- py2b_xmltodict/local/lib/python2.7/site-packages/xmltodict.py  
>> 2016-05-18 11:18:44.0 +0200
>> +++ py2_xmltodict/local/lib/python2.7/site-packages/xmltodict.py   
>> 2016-05-18 11:11:13.417665697 +0200 @@ -35,6 +35,13 @@
>>  __version__ = '0.10.1'
>>  __license__ = 'MIT'
>>
>> +_OrderedDict = OrderedDict
>> +class OrderedDict(_OrderedDict):
>> +def __getitem__(self, key):
>> +if key == 0:
>> +[result] = self.values()
>> +return result
>> +return _OrderedDict.__getitem__(self, key)
>>
>>  class ParsingInterrupted(Exception):
>>  pass
> 
> Easier than patching might be monkeypatching.
> 
> class OrderedDict(OrderedDict):
> ... getitem code as above ...
> xmltodict.OrderedDict = OrderedDict
> 
> Try it, see if it works.

It turns out I was wrong on (at least) two accounts: 

- xmltodict does offer a way to specify the dict type
- the proposed dict implementation will not solve the OP's problem

Here is an improved fix which should work:


$ cat sample.xml 


  
  
  

$ cat sample2.xml 


  
  
  
  

$ cat demo.py
import collections
import sys
import xmltodict


class MyOrderedDict(collections.OrderedDict):
def __getitem__(self, key):
if key == 0 and len(self) == 1:
return self
return super(MyOrderedDict, self).__getitem__(key)


def main():
filename = sys.argv[1]
with open(filename) as f:
doc = xmltodict.parse(f.read(), dict_constructor=MyOrderedDict)

print "doc:\n{}\n".format(doc)
print "package-id: {}".format(
doc['profiles']['profile']['package'][0]['@package-id'])


if __name__ == "__main__":
main()
$ python demo.py sample.xml 
doc:
MyOrderedDict([(u'profiles', MyOrderedDict([(u'profile', 
MyOrderedDict([(u'@id', u'visio02'), (u'@revision', u'2015051501'), 
(u'package', MyOrderedDict([(u'@package-id', u'0964-gpg4win')]))]))]))])

package-id: 0964-gpg4win
$ python demo.py sample2.xml 
doc:
MyOrderedDict([(u'profiles', MyOrderedDict([(u'profile', 
MyOrderedDict([(u'@id', u'visio02'), (u'@revision', u'2015051501'), 
(u'package', [MyOrderedDict([(u'@package-id', u'0964-gpg4win')]), 
MyOrderedDict([(u'@package-id', u'0965-gpg4win')])])]))]))])

package-id: 0964-gpg4win


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


Re: Quote of the day

2016-05-18 Thread Thomas Mlynarczyk
On 17/05/16 12:39, Cem Karan wrote:
> Just downloaded and used a library that came with unit tests, which all 
> passed.
> [...]
> I discovered they had commented out the bodies of some of the unit
tests...

Shouldn't the unit test framework have those "empty" tests reported as
"todo"/"incomplete" or whatever? (I know that PHPUnit reports such tests
as "passed" which I find utterly wrong.)

Thomas

-- 
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: OrderedDict

2016-05-18 Thread Chris Angelico
On Wed, May 18, 2016 at 7:28 PM, Peter Otten <__pete...@web.de> wrote:
> I don't see an official way to pass a custom dict type to the library,
> but if you are not afraid to change its source code the following patch
> will allow you to access the value of dictionaries with a single entry as 
> d[0]:
>
> $ diff -u py2b_xmltodict/local/lib/python2.7/site-packages/xmltodict.py 
> py2_xmltodict/local/lib/python2.7/site-packages/xmltodict.py
> --- py2b_xmltodict/local/lib/python2.7/site-packages/xmltodict.py   
> 2016-05-18 11:18:44.0 +0200
> +++ py2_xmltodict/local/lib/python2.7/site-packages/xmltodict.py
> 2016-05-18 11:11:13.417665697 +0200
> @@ -35,6 +35,13 @@
>  __version__ = '0.10.1'
>  __license__ = 'MIT'
>
> +_OrderedDict = OrderedDict
> +class OrderedDict(_OrderedDict):
> +def __getitem__(self, key):
> +if key == 0:
> +[result] = self.values()
> +return result
> +return _OrderedDict.__getitem__(self, key)
>
>  class ParsingInterrupted(Exception):
>  pass

Easier than patching might be monkeypatching.

class OrderedDict(OrderedDict):
... getitem code as above ...
xmltodict.OrderedDict = OrderedDict

Try it, see if it works.

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


Re: OrderedDict

2016-05-18 Thread Peter Otten
silver0...@gmail.com wrote:

> Hi all,
> 
> I have a understanding problem with return values from xmltodict.
> 
> I have a xml file. Content:
> 
> 
> 
>   
>   
>   
> 
> 
> 
> With code
> 
> __f_name = ''
> with open(__f_name) as __fd:
> __doc = xmltodict.parse(__fd.read())
>
> __doc
> 
> I get
> 
> OrderedDict([(u'profiles', OrderedDict([(u'profile', OrderedDict([(u'@id',
> u'visio02'), (u'@revision', u'2015051501'), (u'package',
> OrderedDict([(u'@package-id', u'0964-gpg4win')]))]))]))])
> 
> If I use
> 
> __doc['profiles']['profile']['package'][0]['@package-id']
> 
> I get
> 
> Traceback (most recent call last):
>   File "", line 1, in 
> KeyError: 0
> 
> If I change xml file like this:
> 
> 
> 
>   
>   
>   
>   
> 
> 
> and run code from above the result is:
> 
> OrderedDict([(u'profiles', OrderedDict([(u'profile', OrderedDict([(u'@id',
> u'visio02'), (u'@revision', u'2015051501'), (u'package',
> [OrderedDict([(u'@package-id', u'0964-gpg4win')]),
> OrderedDict([(u'@package-id', u'0965-gpg4win')])])]))]))])
> 
> No prints __doc['profiles']['profile']['package'][0]['@package-id']:
> 
> u'0964-gpg4win'
> 
> Can everybody explain this?

Not everybody, but Chris and a few others can ;)
 
> Many thanks in advance

I don't see an official way to pass a custom dict type to the library, 
but if you are not afraid to change its source code the following patch
will allow you to access the value of dictionaries with a single entry as d[0]:

$ diff -u py2b_xmltodict/local/lib/python2.7/site-packages/xmltodict.py 
py2_xmltodict/local/lib/python2.7/site-packages/xmltodict.py
--- py2b_xmltodict/local/lib/python2.7/site-packages/xmltodict.py   
2016-05-18 11:18:44.0 +0200
+++ py2_xmltodict/local/lib/python2.7/site-packages/xmltodict.py
2016-05-18 11:11:13.417665697 +0200
@@ -35,6 +35,13 @@
 __version__ = '0.10.1'
 __license__ = 'MIT'
 
+_OrderedDict = OrderedDict
+class OrderedDict(_OrderedDict):
+def __getitem__(self, key):
+if key == 0:
+[result] = self.values()
+return result
+return _OrderedDict.__getitem__(self, key)
 
 class ParsingInterrupted(Exception):
 pass


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


Re: OrderedDict

2016-05-18 Thread Chris Angelico
On Wed, May 18, 2016 at 6:32 PM,   wrote:
> Hi all,
>
> I have a understanding problem with return values from xmltodict.
>
> I have a xml file. Content:
>
> 
> 
>   
>   
>   
> 
>
> 
> 
>   
>   
>   
>   
> 
>
> No prints __doc['profiles']['profile']['package'][0]['@package-id']:
>
> u'0964-gpg4win'
>
> Can everybody explain this?

This is one of the inherent problems of trying to convert XML (a
structured document format) into a nested dictionary (a structured
tree structure). In a dict, you can't have more than one value
associated with a given key; in XML, and similar container-tag-based
structures, you can - as in this example, where you have two package
tags. When that gets converted into a dictionary, they get joined up
into a list, which is why you can subscript it with the integer 0 to
get the first one. If it's not made into a list, subscriping gives you
the next level of dict straight away.

If you're dealing with some files that have one package and some that
have multiple, the easiest way would be something like this:

packages = __doc['profiles']['profile']['package']
if isinstance(packages, dict):
packages = [packages]
for package in packages:
# Do whatever you need with the package
print(package['@package-id'])

Incidentally, the double-leading-underscore names are not what I'd
recommend; use simple names, and if you need them to be private, put
this into a function (which will make them all function-local by
default). The double leading underscore has special meaning inside a
class, which you most likely don't intend.

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


OrderedDict

2016-05-18 Thread silver0346
Hi all,

I have a understanding problem with return values from xmltodict.

I have a xml file. Content:



  
  
  



With code

__f_name = ''
with open(__f_name) as __fd:
__doc = xmltodict.parse(__fd.read())
   
__doc

I get

OrderedDict([(u'profiles', OrderedDict([(u'profile', OrderedDict([(u'@id', 
u'visio02'), (u'@revision', u'2015051501'), (u'package', 
OrderedDict([(u'@package-id', u'0964-gpg4win')]))]))]))])

If I use

__doc['profiles']['profile']['package'][0]['@package-id']

I get 

Traceback (most recent call last):
  File "", line 1, in 
KeyError: 0

If I change xml file like this:



  
  
  
  


and run code from above the result is:

OrderedDict([(u'profiles', OrderedDict([(u'profile', OrderedDict([(u'@id', 
u'visio02'), (u'@revision', u'2015051501'), (u'package', 
[OrderedDict([(u'@package-id', u'0964-gpg4win')]), 
OrderedDict([(u'@package-id', u'0965-gpg4win')])])]))]))])

No prints __doc['profiles']['profile']['package'][0]['@package-id']:

u'0964-gpg4win'

Can everybody explain this?

Many thanks in advance

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