From breamoreboy at yahoo.co.uk  Wed Apr  1 01:19:16 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 01 Apr 2015 00:19:16 +0100
Subject: [Tutor] Unexpected results using enumerate() and .split()
In-Reply-To: <CANDiX9LX0-BGB8ZVaT-SB3adw1Dsv=ja=YCUA8B2aotBQ1H0vQ@mail.gmail.com>
References: <CANDiX9JujZWERrhSx=UcMGdAHbMbatJON9Xw1gupELCwetQhfQ@mail.gmail.com>
 <CAKJDb-OA4mTSqUhSrE=LwNqL-tZWroQe5-sLPXhcS=YYiTC-+A@mail.gmail.com>
 <CANDiX9+HY7p-HL1K-4Tv4atJ7LS_20Gc42f0EBiGVqQ_7KZbxg@mail.gmail.com>
 <CAKJDb-MHw7oNuHqXjwwEptp0VKJ3QrO6xknM0Nst+UX69GksTw@mail.gmail.com>
 <CANDiX9LX0-BGB8ZVaT-SB3adw1Dsv=ja=YCUA8B2aotBQ1H0vQ@mail.gmail.com>
Message-ID: <mffa1p$eik$1@ger.gmane.org>

On 31/03/2015 21:49, boB Stepp wrote:
> On Tue, Mar 31, 2015 at 3:42 PM, Zachary Ware
> <zachary.ware+pytut at gmail.com> wrote:
>
>> Also, not that since you aren't using the index for anything, you
>> don't need to use enumerate() to iterate over the list.  Just do "for
>> item in L:".  Of course, if you actually use the index in the real
>> code that I assume this was cut out of, keep enumerate; it's the right
>> tool for the job.
>
> Yeah, I simplified my actual code into the smallest snippet that I
> could reproduce my problem in. My actual code need the index.
>

Using an index is perhaps the traditional way of doing things but there 
are other options.  As an example you might like to see the pairwise 
function here http://pythonhosted.org//more-itertools/api.html with the 
code available on pypi if you'd like to play.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From mccombs at imperium.org  Wed Apr  1 03:39:45 2015
From: mccombs at imperium.org (P McCombs)
Date: Tue, 31 Mar 2015 18:39:45 -0700
Subject: [Tutor] ArcGIS Create a python script to generate north-facing
 aspect raster from digital elevation model
In-Reply-To: <1426921551.78493.YahooMailBasic@web161005.mail.bf1.yahoo.com>
References: <1426921551.78493.YahooMailBasic@web161005.mail.bf1.yahoo.com>
Message-ID: <CAPEx+EDbsDx=tdg_VF_3g0ynRZwM1yRMxt8osExikoEQMd8Nmg@mail.gmail.com>

On Mar 21, 2015 1:22 AM, "Michael Omohundro"
<momohund1972 at yahoo.com.dmarc.invalid> wrote:
>
> Does anyone know how to create a python script to generate an aspect
raster from the input elevation in a digital elevation model?
>
This topic is out of the normal scope of the mailing list. It's hard to say
if you are having a python issue or an ArcGIS issue.

I could possibly help with the latter,  but please provide the trace back
you get when it errors out,  or how the output differs from what you
expect.

Without the data you are using I'm not going to attempt to run your code.

>
> I need to specify TWO variables as user parameters: input elevation and
output north-facing aspect.
> I need to create an aspect raster from the input elevation from a digital
elevation model.
> I need to find the north facing aspect is the trick, between 0 and 22.5
and between 337.5 ? 360. These are the north facing elevation ranges.
> I need to reclass the north facing aspect into a 1/Nodata raster.
> Any cell is north facing should have value 0, other cells should be
NoData.
> I need to save the results as a permanent raster named as my second input
parameter.
> I can't use ModelBuilder then convert it into Python script.
>
> Here is what I have so far:
>
>
> # Created on: March 20 2015
> # Usage: lab03-5 Aspect from raster surface
> # Requirements: ArcGIS Desktop and Spatial Analyst Extension
> #
---------------------------------------------------------------------------
>
> # Import system modules
> import arcpy
> from arcpy import env
> from arcpy.sa import *
In my experience this makes debugging harder, I can't tell if you are using
local functions or module functions without a detailed knowledge of the
module you imported.

> arcpy.env.overwriteOutput = True
>
> # Set environment settings.  dem30 is the digital elevation model that
holds the elevation data.
> elevation =
r"F:\NW_Missouri_State_University\_Python_Class\Week_10\lab10\dem30"
>
> # North facing elevation 1, range 0 to 22.5
> inRange_North1 = range (0, 22.5, 0.5)
> #North facing elevation 2,range 337.5 - 360
> inRange_North2 = range (337.5, 360, 0.5)
>
> # Set local variables
> inRaster = "elevation"
>
> # Check out the ArcGIS Spatial Analyst extension license
> arcpy.CheckOutExtension("Spatial")
>
> # Execute Aspect
> outAspect = Aspect(inRaster)
>
> # Save the output
>
outAspect.save("F:\NW_Missouri_State_University\_Python_Class\Week_10\lab10\TestLab10_5")
>
> # Specify the current workspace as the workspace where the input
elevation raster is.
> # Extract the base name of the elevation raster.
> arcpy.env.workspace = os.path.dirname(elevation)
> inputElev = os.path.basename(elevation)
>
> # Specify the output raster name as the input elevation name appending
with ?NorthFacing?.
> saveReclass = arcpy.env.workspace + os.sep + inputElev + "NorthFacing"
>
> # Check out the Spatial Analyst extension license for the script.
> arcpy.CheckOutExtension("Spatial")
>
> # Construct a map algebra expression to find the cell with elevation
equal to the range values.
> minRaster = arcpy.sa.Raster(inputElev) = inRange_North1
> maxRaster = arcpy.sa.Raster(inputElev) = inRange_North2
>
> # Construct a map algebra expression to perform a Boolean And
> # operation on the cell values of minRaster and maxRaster.
> # If the cell value is 1 in both raster, then set the output cell value
as 1.
> # Otherwise, set the output cell value as 0. Save the output raster as
variable outRaster.
> outRaster = minRaster & maxRaster
>
> # Create a remap object through RemapValue() function.
> # If the old value is 0, then set the new value as NODATA.
> # If the old value is 1, then set the new value as 1.
>
> remap = arcpy.sa.RemapValue([[0, "NODATA"], [1, 1]])
> outReclassify = arcpy.sa.Reclassify(
>     outRaster, "Value", remap, "NODATA")
>
> #Call the save method on the raster object to save the raster as
permanent dataset.
> outReclassify.save(saveReclass)
>
> # Check in the Spatial Analyst extension license.
> arcpy.CheckInExtension("Spatial")
>
I'm guessing that you've resolved this problem in the past week,  but for
future problems I encourage you to check what data types are expected for
the functions you are calling. They can be unexpected sometimes in arcpy.

Paul McCombs

From cybervigilante at gmail.com  Wed Apr  1 06:50:43 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Tue, 31 Mar 2015 21:50:43 -0700
Subject: [Tutor] Python Idioms?
Message-ID: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>

I'm looking at this and can't see how it works, although I understand
zipping and unpacking. The docs say it's a Python idiom. Does "idiom" mean
it works in a special way so I can't figure it out from basic principles?
It looks to me like the iterator in the list gets doubled, so the zip
should make it [(1,1),(2,2),(3,3),... ], not [(1,2),(3,4),...]

What am I missing here?

>>> s = [1,2,3,4,5,6,7,8]
>>> list(zip(*[iter(s)]*2))
>>> [(1, 2), (3, 4), (5, 6), (7, 8)]

https://docs.python.org/3/library/functions.html#zip



-- 
Jim

From alan.gauld at btinternet.com  Wed Apr  1 11:04:15 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 01 Apr 2015 10:04:15 +0100
Subject: [Tutor] Python Idioms?
In-Reply-To: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
References: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
Message-ID: <mfgcaf$d2c$1@ger.gmane.org>

On 01/04/15 05:50, Jim Mooney wrote:
> I'm looking at this and can't see how it works, although I understand
> zipping and unpacking. The docs say it's a Python idiom. Does "idiom" mean
> it works in a special way so I can't figure it out from basic principles?

No idiom means a common pattern of usage in the community.
In this case thats true of zip(), its less true of this
case which is somewhat obscure.

> It looks to me like the iterator in the list gets doubled, so the zip
> should make it [(1,1),(2,2),(3,3),... ], not [(1,2),(3,4),...]
>
> What am I missing here?

The fact that thew list contains a reference to an iterator
so when you multiply by two you get two references
to *the same* iterator.

So each time the iterator gets accessed it returns the next
number in the sequence, not the same number twice.

>>>> s = [1,2,3,4,5,6,7,8]
>>>> list(zip(*[iter(s)]*2))
>>>> [(1, 2), (3, 4), (5, 6), (7, 8)]

Personally I'd have used slicing in this example:

zip(s[::2],s[1::2])

Is that any clearer?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From wolfgang.maier at biologie.uni-freiburg.de  Wed Apr  1 12:04:34 2015
From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier)
Date: Wed, 01 Apr 2015 12:04:34 +0200
Subject: [Tutor] Python Idioms?
In-Reply-To: <mfgcaf$d2c$1@ger.gmane.org>
References: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
 <mfgcaf$d2c$1@ger.gmane.org>
Message-ID: <mfgft4$err$1@ger.gmane.org>

On 04/01/2015 11:04 AM, Alan Gauld wrote:
> On 01/04/15 05:50, Jim Mooney wrote:
>
>>>>> s = [1,2,3,4,5,6,7,8]
>>>>> list(zip(*[iter(s)]*2))
>>>>> [(1, 2), (3, 4), (5, 6), (7, 8)]
>
> Personally I'd have used slicing in this example:
>
> zip(s[::2],s[1::2])
>

With an emphasis on *in this example*.

The idiom you are citing works on any iterable, not all of which support 
slicing and the slicing version requires two passes over the data.


From alan.gauld at btinternet.com  Wed Apr  1 12:50:11 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 01 Apr 2015 11:50:11 +0100
Subject: [Tutor] Python Idioms?
In-Reply-To: <mfgft4$err$1@ger.gmane.org>
References: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
 <mfgcaf$d2c$1@ger.gmane.org> <mfgft4$err$1@ger.gmane.org>
Message-ID: <mfgih3$uni$1@ger.gmane.org>

On 01/04/15 11:04, Wolfgang Maier wrote:
> On 04/01/2015 11:04 AM, Alan Gauld wrote:
>> On 01/04/15 05:50, Jim Mooney wrote:
>>
>>>>>> s = [1,2,3,4,5,6,7,8]
>>>>>> list(zip(*[iter(s)]*2))
>>>>>> [(1, 2), (3, 4), (5, 6), (7, 8)]
>>
>> Personally I'd have used slicing in this example:
>>
>> zip(s[::2],s[1::2])
>>
>
> With an emphasis on *in this example*.
>
> The idiom you are citing works on any iterable, not all of which support
> slicing and the slicing version requires two passes over the data.

Agreed, but readability always trumps performance,
unless performance is critical.
In which case readability usually trumps performance.

And especially on a beginners list.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From breamoreboy at yahoo.co.uk  Wed Apr  1 13:06:33 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 01 Apr 2015 12:06:33 +0100
Subject: [Tutor] Python Idioms?
In-Reply-To: <mfgih3$uni$1@ger.gmane.org>
References: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
 <mfgcaf$d2c$1@ger.gmane.org> <mfgft4$err$1@ger.gmane.org>
 <mfgih3$uni$1@ger.gmane.org>
Message-ID: <mfgjft$ge0$1@ger.gmane.org>

On 01/04/2015 11:50, Alan Gauld wrote:
> On 01/04/15 11:04, Wolfgang Maier wrote:
>> On 04/01/2015 11:04 AM, Alan Gauld wrote:
>>> On 01/04/15 05:50, Jim Mooney wrote:
>>>
>>>>>>> s = [1,2,3,4,5,6,7,8]
>>>>>>> list(zip(*[iter(s)]*2))
>>>>>>> [(1, 2), (3, 4), (5, 6), (7, 8)]
>>>
>>> Personally I'd have used slicing in this example:
>>>
>>> zip(s[::2],s[1::2])
>>>
>>
>> With an emphasis on *in this example*.
>>
>> The idiom you are citing works on any iterable, not all of which support
>> slicing and the slicing version requires two passes over the data.
>
> Agreed, but readability always trumps performance,
> unless performance is critical.
> In which case readability usually trumps performance.
>
> And especially on a beginners list.
>

In which case I'll stick with the more-itertools pairwise() function 
which I pointed out on another thread just yesterday.  From 
http://pythonhosted.org//more-itertools/api.html

<quote>
Returns an iterator of paired items, overlapping, from the original

 >>> take(4, pairwise(count()))
[(0, 1), (1, 2), (2, 3), (3, 4)]
</quote>

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From davea at davea.name  Wed Apr  1 14:45:44 2015
From: davea at davea.name (Dave Angel)
Date: Wed, 01 Apr 2015 08:45:44 -0400
Subject: [Tutor] Python Idioms?
In-Reply-To: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
References: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
Message-ID: <551BE878.7070901@davea.name>

On 04/01/2015 12:50 AM, Jim Mooney wrote:
> I'm looking at this and can't see how it works, although I understand
> zipping and unpacking. The docs say it's a Python idiom. Does "idiom" mean
> it works in a special way so I can't figure it out from basic principles?
> It looks to me like the iterator in the list gets doubled, so the zip
> should make it [(1,1),(2,2),(3,3),... ], not [(1,2),(3,4),...]
>
> What am I missing here?
>
>>>> s = [1,2,3,4,5,6,7,8]
>>>> list(zip(*[iter(s)]*2))
>>>> [(1, 2), (3, 4), (5, 6), (7, 8)]
>
> https://docs.python.org/3/library/functions.html#zip
>


In that same thread, Peter Otten posted the following, which I think is 
probably a bit clearer:


 >>> flat_pairs = ['broadcast', '"d8on"', 'broadcast', '"d11on"']
 >>> it = iter(flat_pairs)
 >>> pairs = list(zip(it, it))
 >>> pairs

That does exactly the same thing, but in the first one you can replace 
the '2' with a variable, to make variable sized tuples.

In both cases, the trick is that the same iterator is used twice in the 
expression, so even though zip is taking one from each, there are no 
duplications.

If you know the original data is a list, or at least that it can do 
slices, then you can do Alan's suggestion:


zip(s[::2],s[1::2])

Or you could try:

from itertools import islice

pairs = zip(islice(s, 0, 9999, 2), islice(s, 1, 9999, 2))



-- 
DaveA

From steve at pearwood.info  Wed Apr  1 15:01:44 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 2 Apr 2015 00:01:44 +1100
Subject: [Tutor] Python Idioms?
In-Reply-To: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
References: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
Message-ID: <20150401130143.GT25453@ando.pearwood.info>

On Tue, Mar 31, 2015 at 09:50:43PM -0700, Jim Mooney wrote:
> I'm looking at this and can't see how it works, although I understand
> zipping and unpacking. The docs say it's a Python idiom. Does "idiom" mean
> it works in a special way so I can't figure it out from basic principles?
> It looks to me like the iterator in the list gets doubled, so the zip
> should make it [(1,1),(2,2),(3,3),... ], not [(1,2),(3,4),...]
> 
> What am I missing here?

The secret is that list multiplication doesn't make *copies*, it 
replicates multiple references to the same object.

> >>> s = [1,2,3,4,5,6,7,8]
> >>> list(zip(*[iter(s)]*2))
> >>> [(1, 2), (3, 4), (5, 6), (7, 8)]


Let's pull this apart and see how it ticks. It may actually be more 
obvious what is going on if we use more than two references, and do by 
hand what * does for us above.

py> s = [100, 200, 300, 400, 500, 600, 700, 800, 900]
py> it = iter(s)  # One iterator object.
py> next(it), next(it), next(it)  # Call next three times.
(100, 200, 300)
py> args = [it, it, it]  # Like [it]*3
py> for x in args:
...     print(next(x))  # Like next(it).
...
400
500
600


We created *one* iterator. First we called next(it) three times, by 
hand, which yields the first three items in the list s. Then we stick 
the iterator in a new list three times, and loop over that, calling 
next() each time. That is equivalent to next(it) three more times, which 
gives us the next three items.

Finally, we pass them to zip(), as separate arguments:

py> list(zip(*args))
[(700, 800, 900)]


Which gives us the next three items. At that point, we run out of items, 
and zip completes.

Putting it (almost) all together now. Remember that `it` above, the 
iterator, is now exhausted. It has walked all the way through list s, so 
we need a new iterator to make it work again:

py> list(it)  # it is exhausted.
[]
py> it = iter(s)  # So re-create it.
py> list(zip(*[it]*3))
[(100, 200, 300), (400, 500, 600), (700, 800, 900)]


We can avoid the temporary variable:

py> list(zip(*[iter(s)]*3))
[(100, 200, 300), (400, 500, 600), (700, 800, 900)]


-- 
Steve

From steve at pearwood.info  Wed Apr  1 15:16:30 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 2 Apr 2015 00:16:30 +1100
Subject: [Tutor] Python Idioms?
In-Reply-To: <mfgjft$ge0$1@ger.gmane.org>
References: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
 <mfgcaf$d2c$1@ger.gmane.org> <mfgft4$err$1@ger.gmane.org>
 <mfgih3$uni$1@ger.gmane.org> <mfgjft$ge0$1@ger.gmane.org>
Message-ID: <20150401131630.GU25453@ando.pearwood.info>

On Wed, Apr 01, 2015 at 12:06:33PM +0100, Mark Lawrence wrote:

> In which case I'll stick with the more-itertools pairwise() function 
> which I pointed out on another thread just yesterday.  From 
> http://pythonhosted.org//more-itertools/api.html
> 
> <quote>
> Returns an iterator of paired items, overlapping, from the original
> 
> >>> take(4, pairwise(count()))
> [(0, 1), (1, 2), (2, 3), (3, 4)]

I betcha the implementation of pairwise is something really close to:

def pairwise(iterable):
    it = iter(iterable)
    return itertools.izip(it, it)

for Python 2, and for Python 3:

def pairwise(iterable):
    it = iter(iterable)
    return zip(it, it)



which is all well and good, but what if you want triplets, not pairs?

def threewise(iterable):
    it = iter(iterable)
    return zip(it, it, it)

I don't think it's very practical to include a *wise for every possible 
number of items...


Let's deal some cards!

import random
cards = []
for value in "A 2 3 4 5 6 7 8 9 10 J Q K".split():
    for suit in u"????":
        cards.append(value + suit)

random.shuffle(cards)
deck = iter(cards)
hands = zip(*[deck]*8)
for name in "Groucho Chico Harpo Zeppo Gummo".split():
    print("%s gets dealt %s" % (name, ','.join(next(hands))))



I get these results, but being random of course you will get something 
different:

Groucho gets dealt 8?,2?,5?,7?,8?,7?,6?,8?
Chico gets dealt Q?,K?,3?,7?,K?,J?,9?,10?
Harpo gets dealt 10?,4?,4?,A?,A?,K?,3?,J?
Zeppo gets dealt 5?,A?,3?,Q?,9?,9?,4?,2?
Gummo gets dealt J?,Q?,4?,10?,J?,6?,5?,A?



-- 
Steve

From breamoreboy at yahoo.co.uk  Wed Apr  1 16:19:11 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 01 Apr 2015 15:19:11 +0100
Subject: [Tutor] Python Idioms?
In-Reply-To: <20150401131630.GU25453@ando.pearwood.info>
References: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
 <mfgcaf$d2c$1@ger.gmane.org> <mfgft4$err$1@ger.gmane.org>
 <mfgih3$uni$1@ger.gmane.org> <mfgjft$ge0$1@ger.gmane.org>
 <20150401131630.GU25453@ando.pearwood.info>
Message-ID: <mfguov$u6e$1@ger.gmane.org>

On 01/04/2015 14:16, Steven D'Aprano wrote:
> On Wed, Apr 01, 2015 at 12:06:33PM +0100, Mark Lawrence wrote:
>
>> In which case I'll stick with the more-itertools pairwise() function
>> which I pointed out on another thread just yesterday.  From
>> http://pythonhosted.org//more-itertools/api.html
>>
>> <quote>
>> Returns an iterator of paired items, overlapping, from the original
>>
>>>>> take(4, pairwise(count()))
>> [(0, 1), (1, 2), (2, 3), (3, 4)]
>
> I betcha the implementation of pairwise is something really close to:
>
> def pairwise(iterable):
>      it = iter(iterable)
>      return itertools.izip(it, it)
>
> for Python 2, and for Python 3:
>
> def pairwise(iterable):
>      it = iter(iterable)
>      return zip(it, it)
>

Not a bad attempt :)  It's actually.

def pairwise(iterable):
     """Returns an iterator of paired items, overlapping, from the original

         >>> take(4, pairwise(count()))
         [(0, 1), (1, 2), (2, 3), (3, 4)]

     """
     a, b = tee(iterable)
     next(b, None)
     return zip(a, b)

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From colin.ross.dal at gmail.com  Wed Apr  1 16:43:56 2015
From: colin.ross.dal at gmail.com (Colin Ross)
Date: Wed, 1 Apr 2015 11:43:56 -0300
Subject: [Tutor] Python serial interface
Message-ID: <CAB80X9GjC_cMOprSQmH5xsa+Y9yjLA=+4vShsPANoiXLUvA_ZQ@mail.gmail.com>

Hi all,

This is a very general question, but I was wondering if anyone has
experience using python to interface with a serial port? If so, can you
please forward any useful resources?

Thanks!

Colin

From francois.dion at gmail.com  Wed Apr  1 16:53:17 2015
From: francois.dion at gmail.com (Francois Dion)
Date: Wed, 1 Apr 2015 10:53:17 -0400
Subject: [Tutor] Python serial interface
In-Reply-To: <CAB80X9GjC_cMOprSQmH5xsa+Y9yjLA=+4vShsPANoiXLUvA_ZQ@mail.gmail.com>
References: <CAB80X9GjC_cMOprSQmH5xsa+Y9yjLA=+4vShsPANoiXLUvA_ZQ@mail.gmail.com>
Message-ID: <CAOLi1KA5X_U5x4TGRDyqvy1qQUvGSs-7pERq3Lvaw3Cu-A0MOg@mail.gmail.com>

Pyserial is python 2.x and 3.x compatible. It is very widely used and is
stable.

http://pyserial.sourceforge.net/

What is your application? Sometimes you can use a higher level module that
makes use of pyserial.

Francois
--
raspberry-python.blogspot.com - www.pyptug.org - www.3DFutureTech.info -
@f_dion

From breamoreboy at yahoo.co.uk  Wed Apr  1 16:56:35 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 01 Apr 2015 15:56:35 +0100
Subject: [Tutor] Python serial interface
In-Reply-To: <CAB80X9GjC_cMOprSQmH5xsa+Y9yjLA=+4vShsPANoiXLUvA_ZQ@mail.gmail.com>
References: <CAB80X9GjC_cMOprSQmH5xsa+Y9yjLA=+4vShsPANoiXLUvA_ZQ@mail.gmail.com>
Message-ID: <mfh0v3$1l3$1@ger.gmane.org>

On 01/04/2015 15:43, Colin Ross wrote:
> Hi all,
>
> This is a very general question, but I was wondering if anyone has
> experience using python to interface with a serial port? If so, can you
> please forward any useful resources?
>
> Thanks!
>
> Colin
>

http://pyserial.sourceforge.net/

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From colin.ross.dal at gmail.com  Wed Apr  1 17:01:31 2015
From: colin.ross.dal at gmail.com (Colin Ross)
Date: Wed, 1 Apr 2015 12:01:31 -0300
Subject: [Tutor] Python serial interface
In-Reply-To: <CAOLi1KA5X_U5x4TGRDyqvy1qQUvGSs-7pERq3Lvaw3Cu-A0MOg@mail.gmail.com>
References: <CAB80X9GjC_cMOprSQmH5xsa+Y9yjLA=+4vShsPANoiXLUvA_ZQ@mail.gmail.com>
 <CAOLi1KA5X_U5x4TGRDyqvy1qQUvGSs-7pERq3Lvaw3Cu-A0MOg@mail.gmail.com>
Message-ID: <CAB80X9G+CC8qe=uaPekYPE=5PccCqAN6OdycL9i2XKbQNm3dgQ@mail.gmail.com>

Hi Francois,

Thank you for the fast reply! I am looking to control a brushless servo
motor (
http://www.aerotech.com/product-catalog/motors/rotary-motors/bms-series.aspx)
that drives a rotary stage.

Colin

On Wed, Apr 1, 2015 at 11:53 AM, Francois Dion <francois.dion at gmail.com>
wrote:

> Pyserial is python 2.x and 3.x compatible. It is very widely used and is
> stable.
>
> http://pyserial.sourceforge.net/
>
> What is your application? Sometimes you can use a higher level module that
> makes use of pyserial.
>
> Francois
> --
> raspberry-python.blogspot.com - www.pyptug.org - www.3DFutureTech.info -
> @f_dion
>

From francois.dion at gmail.com  Wed Apr  1 17:50:13 2015
From: francois.dion at gmail.com (Francois Dion)
Date: Wed, 1 Apr 2015 11:50:13 -0400
Subject: [Tutor] Python serial interface
In-Reply-To: <CAB80X9G+CC8qe=uaPekYPE=5PccCqAN6OdycL9i2XKbQNm3dgQ@mail.gmail.com>
References: <CAB80X9GjC_cMOprSQmH5xsa+Y9yjLA=+4vShsPANoiXLUvA_ZQ@mail.gmail.com>
 <CAOLi1KA5X_U5x4TGRDyqvy1qQUvGSs-7pERq3Lvaw3Cu-A0MOg@mail.gmail.com>
 <CAB80X9G+CC8qe=uaPekYPE=5PccCqAN6OdycL9i2XKbQNm3dgQ@mail.gmail.com>
Message-ID: <CAOLi1KB198U88UOcRdiy9GzXoCCy6cN-+WpvWVLhC12QJ_=r3A@mail.gmail.com>

On Wed, Apr 1, 2015 at 11:01 AM, Colin Ross <colin.ross.dal at gmail.com>
wrote:

> Hi Francois,
>
> Thank you for the fast reply! I am looking to control a brushless servo
> motor (
> http://www.aerotech.com/product-catalog/motors/rotary-motors/bms-series.aspx)
> that drives a rotary stage.
>

These motors are not controlled by serial, you'll need a brushless
controller. In turn the controller might be or not serial, or ip or
something else altogether (PWM is typical). They do have an rs-422
connection, but that is for a feedback signal. So you are building a
feedback control system. If you google that and python you'll find several
useful references, including a design and analysis module (but not control):

https://pypi.python.org/pypi/control/0.6.6
http://sourceforge.net/projects/python-control/

Nothing out of the box for your application, obviously. Also, the motor
control itself will depend on the microprocessor hardware you are using and
the motor controller. Assuming PWM, the raspberry pi has a software PWM
module in Python. Same with micropython. Anything else is pretty much DIY.

As for the overall concept of control systems, Chapter 9 of "Real World
Instrumentation" ( http://shop.oreilly.com/product/9780596809577.do ) will
give you an overview of what is involved (with some python example, but not
directly applicable to your system).

Francois
--
raspberry-python.blogspot.com - www.pyptug.org - www.3DFutureTech.info
<http://www.3dfuturetech.info/> - @f_dion

From colin.ross.dal at gmail.com  Wed Apr  1 17:58:17 2015
From: colin.ross.dal at gmail.com (Colin Ross)
Date: Wed, 1 Apr 2015 12:58:17 -0300
Subject: [Tutor] Python serial interface
In-Reply-To: <CAOLi1KB198U88UOcRdiy9GzXoCCy6cN-+WpvWVLhC12QJ_=r3A@mail.gmail.com>
References: <CAB80X9GjC_cMOprSQmH5xsa+Y9yjLA=+4vShsPANoiXLUvA_ZQ@mail.gmail.com>
 <CAOLi1KA5X_U5x4TGRDyqvy1qQUvGSs-7pERq3Lvaw3Cu-A0MOg@mail.gmail.com>
 <CAB80X9G+CC8qe=uaPekYPE=5PccCqAN6OdycL9i2XKbQNm3dgQ@mail.gmail.com>
 <CAOLi1KB198U88UOcRdiy9GzXoCCy6cN-+WpvWVLhC12QJ_=r3A@mail.gmail.com>
Message-ID: <CAB80X9E2SJShVF8ibFrGRXGG9D8CLLR6ixZF7YPC2qz5hhmDoQ@mail.gmail.com>

Thank you Francois, this gives me a lot to think about!

I really appreciate your feedback.

Colin

On Wed, Apr 1, 2015 at 12:50 PM, Francois Dion <francois.dion at gmail.com>
wrote:

> On Wed, Apr 1, 2015 at 11:01 AM, Colin Ross <colin.ross.dal at gmail.com>
> wrote:
>
>> Hi Francois,
>>
>> Thank you for the fast reply! I am looking to control a brushless servo
>> motor (
>> http://www.aerotech.com/product-catalog/motors/rotary-motors/bms-series.aspx)
>> that drives a rotary stage.
>>
>
> These motors are not controlled by serial, you'll need a brushless
> controller. In turn the controller might be or not serial, or ip or
> something else altogether (PWM is typical). They do have an rs-422
> connection, but that is for a feedback signal. So you are building a
> feedback control system. If you google that and python you'll find several
> useful references, including a design and analysis module (but not control):
>
> https://pypi.python.org/pypi/control/0.6.6
> http://sourceforge.net/projects/python-control/
>
> Nothing out of the box for your application, obviously. Also, the motor
> control itself will depend on the microprocessor hardware you are using and
> the motor controller. Assuming PWM, the raspberry pi has a software PWM
> module in Python. Same with micropython. Anything else is pretty much DIY.
>
> As for the overall concept of control systems, Chapter 9 of "Real World
> Instrumentation" ( http://shop.oreilly.com/product/9780596809577.do )
> will give you an overview of what is involved (with some python example,
> but not directly applicable to your system).
>
> Francois
> --
> raspberry-python.blogspot.com - www.pyptug.org - www.3DFutureTech.info
> <http://www.3dfuturetech.info/> - @f_dion
>

From colin.ross.dal at gmail.com  Wed Apr  1 18:14:54 2015
From: colin.ross.dal at gmail.com (Colin Ross)
Date: Wed, 1 Apr 2015 13:14:54 -0300
Subject: [Tutor] Python serial interface
In-Reply-To: <CAB80X9E2SJShVF8ibFrGRXGG9D8CLLR6ixZF7YPC2qz5hhmDoQ@mail.gmail.com>
References: <CAB80X9GjC_cMOprSQmH5xsa+Y9yjLA=+4vShsPANoiXLUvA_ZQ@mail.gmail.com>
 <CAOLi1KA5X_U5x4TGRDyqvy1qQUvGSs-7pERq3Lvaw3Cu-A0MOg@mail.gmail.com>
 <CAB80X9G+CC8qe=uaPekYPE=5PccCqAN6OdycL9i2XKbQNm3dgQ@mail.gmail.com>
 <CAOLi1KB198U88UOcRdiy9GzXoCCy6cN-+WpvWVLhC12QJ_=r3A@mail.gmail.com>
 <CAB80X9E2SJShVF8ibFrGRXGG9D8CLLR6ixZF7YPC2qz5hhmDoQ@mail.gmail.com>
Message-ID: <CAB80X9HrkM+9t8XmXdhiC8C3PjzvOPQ_Wc6AgGrGiW2T3EnbEA@mail.gmail.com>

I am using the following controller:

http://www.aerotech.com/product-catalog/drives-and-drive-racks/ensemble-mp.aspx

Which does not specifically list python as one of the accepted languages,
but I guess this does not mean it is not possible.

Colin

On Wed, Apr 1, 2015 at 12:58 PM, Colin Ross <colin.ross.dal at gmail.com>
wrote:

> Thank you Francois, this gives me a lot to think about!
>
> I really appreciate your feedback.
>
> Colin
>
> On Wed, Apr 1, 2015 at 12:50 PM, Francois Dion <francois.dion at gmail.com>
> wrote:
>
>> On Wed, Apr 1, 2015 at 11:01 AM, Colin Ross <colin.ross.dal at gmail.com>
>> wrote:
>>
>>> Hi Francois,
>>>
>>> Thank you for the fast reply! I am looking to control a brushless servo
>>> motor (
>>> http://www.aerotech.com/product-catalog/motors/rotary-motors/bms-series.aspx)
>>> that drives a rotary stage.
>>>
>>
>> These motors are not controlled by serial, you'll need a brushless
>> controller. In turn the controller might be or not serial, or ip or
>> something else altogether (PWM is typical). They do have an rs-422
>> connection, but that is for a feedback signal. So you are building a
>> feedback control system. If you google that and python you'll find several
>> useful references, including a design and analysis module (but not control):
>>
>> https://pypi.python.org/pypi/control/0.6.6
>> http://sourceforge.net/projects/python-control/
>>
>> Nothing out of the box for your application, obviously. Also, the motor
>> control itself will depend on the microprocessor hardware you are using and
>> the motor controller. Assuming PWM, the raspberry pi has a software PWM
>> module in Python. Same with micropython. Anything else is pretty much DIY.
>>
>> As for the overall concept of control systems, Chapter 9 of "Real World
>> Instrumentation" ( http://shop.oreilly.com/product/9780596809577.do )
>> will give you an overview of what is involved (with some python example,
>> but not directly applicable to your system).
>>
>> Francois
>> --
>> raspberry-python.blogspot.com - www.pyptug.org - www.3DFutureTech.info
>> <http://www.3dfuturetech.info/> - @f_dion
>>
>
>

From roel at roelschroeven.net  Wed Apr  1 19:20:12 2015
From: roel at roelschroeven.net (Roel Schroeven)
Date: Wed, 01 Apr 2015 19:20:12 +0200
Subject: [Tutor] Python Idioms?
In-Reply-To: <mfgjft$ge0$1@ger.gmane.org>
References: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
 <mfgcaf$d2c$1@ger.gmane.org> <mfgft4$err$1@ger.gmane.org>
 <mfgih3$uni$1@ger.gmane.org> <mfgjft$ge0$1@ger.gmane.org>
Message-ID: <mfh9cc$h8u$1@ger.gmane.org>

Mark Lawrence schreef:
> On 01/04/2015 11:50, Alan Gauld wrote:
>> On 01/04/15 11:04, Wolfgang Maier wrote:
>>> On 04/01/2015 11:04 AM, Alan Gauld wrote:
>>>> On 01/04/15 05:50, Jim Mooney wrote:
>>>>
>>>>>>>> s = [1,2,3,4,5,6,7,8]
>>>>>>>> list(zip(*[iter(s)]*2))
>>>>>>>> [(1, 2), (3, 4), (5, 6), (7, 8)]
>>>> Personally I'd have used slicing in this example:
>>>>
>>>> zip(s[::2],s[1::2])
>>>>
>>> With an emphasis on *in this example*.
>>>
>>> The idiom you are citing works on any iterable, not all of which support
>>> slicing and the slicing version requires two passes over the data.
>> Agreed, but readability always trumps performance,
>> unless performance is critical.
>> In which case readability usually trumps performance.
>>
>> And especially on a beginners list.
>>
> 
> In which case I'll stick with the more-itertools pairwise() function 

Which does not the same thing. Original:

 >>>>>>>> s = [1,2,3,4,5,6,7,8]
 >>>>>>>> list(zip(*[iter(s)]*2))
 >>>>>>>> [(1, 2), (3, 4), (5, 6), (7, 8)]

Pairwise:

>  >>> take(4, pairwise(count()))
> [(0, 1), (1, 2), (2, 3), (3, 4)]


Greetings,
Roel

-- 
The saddest aspect of life right now is that science gathers knowledge
faster than society gathers wisdom.
   -- Isaac Asimov

Roel Schroeven


From breamoreboy at yahoo.co.uk  Wed Apr  1 22:25:27 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 01 Apr 2015 21:25:27 +0100
Subject: [Tutor] Python serial interface
In-Reply-To: <CAB80X9HrkM+9t8XmXdhiC8C3PjzvOPQ_Wc6AgGrGiW2T3EnbEA@mail.gmail.com>
References: <CAB80X9GjC_cMOprSQmH5xsa+Y9yjLA=+4vShsPANoiXLUvA_ZQ@mail.gmail.com>
 <CAOLi1KA5X_U5x4TGRDyqvy1qQUvGSs-7pERq3Lvaw3Cu-A0MOg@mail.gmail.com>
 <CAB80X9G+CC8qe=uaPekYPE=5PccCqAN6OdycL9i2XKbQNm3dgQ@mail.gmail.com>
 <CAOLi1KB198U88UOcRdiy9GzXoCCy6cN-+WpvWVLhC12QJ_=r3A@mail.gmail.com>
 <CAB80X9E2SJShVF8ibFrGRXGG9D8CLLR6ixZF7YPC2qz5hhmDoQ@mail.gmail.com>
 <CAB80X9HrkM+9t8XmXdhiC8C3PjzvOPQ_Wc6AgGrGiW2T3EnbEA@mail.gmail.com>
Message-ID: <mfhk7o$cq6$1@ger.gmane.org>

On 01/04/2015 17:14, Colin Ross wrote:
> I am using the following controller:
>
> http://www.aerotech.com/product-catalog/drives-and-drive-racks/ensemble-mp.aspx
>
> Which does not specifically list python as one of the accepted languages,
> but I guess this does not mean it is not possible.
>
> Colin


Can you please stop top posting, it's extremely irritating trying to 
follow fairly long threads like this, thanks.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From breamoreboy at yahoo.co.uk  Wed Apr  1 22:59:30 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 01 Apr 2015 21:59:30 +0100
Subject: [Tutor] Python Idioms?
In-Reply-To: <mfh9cc$h8u$1@ger.gmane.org>
References: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
 <mfgcaf$d2c$1@ger.gmane.org> <mfgft4$err$1@ger.gmane.org>
 <mfgih3$uni$1@ger.gmane.org> <mfgjft$ge0$1@ger.gmane.org>
 <mfh9cc$h8u$1@ger.gmane.org>
Message-ID: <mfhm7j$e08$1@ger.gmane.org>

On 01/04/2015 18:20, Roel Schroeven wrote:
> Mark Lawrence schreef:
>> On 01/04/2015 11:50, Alan Gauld wrote:
>>> On 01/04/15 11:04, Wolfgang Maier wrote:
>>>> On 04/01/2015 11:04 AM, Alan Gauld wrote:
>>>>> On 01/04/15 05:50, Jim Mooney wrote:
>>>>>
>>>>>>>>> s = [1,2,3,4,5,6,7,8]
>>>>>>>>> list(zip(*[iter(s)]*2))
>>>>>>>>> [(1, 2), (3, 4), (5, 6), (7, 8)]
>>>>> Personally I'd have used slicing in this example:
>>>>>
>>>>> zip(s[::2],s[1::2])
>>>>>
>>>> With an emphasis on *in this example*.
>>>>
>>>> The idiom you are citing works on any iterable, not all of which
>>>> support
>>>> slicing and the slicing version requires two passes over the data.
>>> Agreed, but readability always trumps performance,
>>> unless performance is critical.
>>> In which case readability usually trumps performance.
>>>
>>> And especially on a beginners list.
>>>
>>
>> In which case I'll stick with the more-itertools pairwise() function
>
> Which does not the same thing. Original:
>
>  >>>>>>>> s = [1,2,3,4,5,6,7,8]
>  >>>>>>>> list(zip(*[iter(s)]*2))
>  >>>>>>>> [(1, 2), (3, 4), (5, 6), (7, 8)]
>
> Pairwise:
>
>>  >>> take(4, pairwise(count()))
>> [(0, 1), (1, 2), (2, 3), (3, 4)]
>
>
> Greetings,
> Roel
>

Yo are of course completely correct, I was conflating two different 
threads :)

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From steve at pearwood.info  Thu Apr  2 00:08:59 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 2 Apr 2015 09:08:59 +1100
Subject: [Tutor] Python Idioms?
In-Reply-To: <mfhm7j$e08$1@ger.gmane.org>
References: <CALRAYNWpzGe1HGbFhsR2Rewx6fss1p2RDdMG2LZwWLb7d_Zk8w@mail.gmail.com>
 <mfgcaf$d2c$1@ger.gmane.org> <mfgft4$err$1@ger.gmane.org>
 <mfgih3$uni$1@ger.gmane.org> <mfgjft$ge0$1@ger.gmane.org>
 <mfh9cc$h8u$1@ger.gmane.org> <mfhm7j$e08$1@ger.gmane.org>
Message-ID: <20150401220858.GV25453@ando.pearwood.info>

On Wed, Apr 01, 2015 at 09:59:30PM +0100, Mark Lawrence wrote:
[snip mass quoting]
> Yo are of course completely correct, I was conflating two different 
> threads :)


Hey guys, how about trimming some of the excessive quoting in your 
posts? Especially if you're going to complain about the annoyance of 
top-posting, bottom-posting without trimming is actually *worse* and 
more distruptive to ease of reading. After I've flipped through two 
pages of quotes without any new comments at all, I'm sorely tempted to 
just hit Delete on the rest unread.


-- 
Steve

From abdalimran at live.com  Wed Apr  1 21:22:05 2015
From: abdalimran at live.com (Abdullah Al Imran)
Date: Thu, 2 Apr 2015 01:22:05 +0600
Subject: [Tutor] How do I make pattern to find only '.html' file using
 Python Regular Expression?
Message-ID: <COL131-W577CCEFEB282AFBDBEB230B0F30@phx.gbl>

I have some HTML content where there are many links as the following pattern:

<a href="http://example.com/2013/01/problem1.html">Problem No-1</a><br />

I want to filter all the links  into a list as:
['http://example.com/2013/01/problem1.html', 'http://example.com/2013/02/problem2.html']

How to do it using Python Regular Expression?

If I want to filter all the links into a dictionary as: 
['http://example.com/2013/01/problem1.html':'Problem No-1', 'http://example.com/2013/02/problem2.html ':'Problem No-2',]

How do I do it? 		 	   		  

From alan.gauld at btinternet.com  Thu Apr  2 01:02:17 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 02 Apr 2015 00:02:17 +0100
Subject: [Tutor] How do I make pattern to find only '.html' file using
 Python Regular Expression?
In-Reply-To: <COL131-W577CCEFEB282AFBDBEB230B0F30@phx.gbl>
References: <COL131-W577CCEFEB282AFBDBEB230B0F30@phx.gbl>
Message-ID: <mfhtdp$u5q$1@ger.gmane.org>

On 01/04/15 20:22, Abdullah Al Imran wrote:
> I have some HTML content where there are many links as the following pattern:
>
> <a href="http://example.com/2013/01/problem1.html">Problem No-1</a><br />
>
> I want to filter all the links  into a list as:
> ['http://example.com/2013/01/problem1.html', 'http://example.com/2013/02/problem2.html']
>
> How to do it using Python Regular Expression?

You can try, but regular expressions are not a reliable way
to parse HTML.

You are much better to use a dedicated HTML parser such
as the one  found in  htmllib in the standard library or
a third party tool like BeautifulSoup.

These recognise the different tag types and separate the content
and data for you. You can then just ask for the parser to
find <a...> tags and then fetch the data from each tag.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From ben+python at benfinney.id.au  Thu Apr  2 01:47:21 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Thu, 02 Apr 2015 10:47:21 +1100
Subject: [Tutor] How do I make pattern to find only '.html' file using
	Python Regular Expression?
References: <COL131-W577CCEFEB282AFBDBEB230B0F30@phx.gbl>
Message-ID: <85k2xv1kdy.fsf@benfinney.id.au>

Abdullah Al Imran <abdalimran at live.com> writes:

> How to do it using Python Regular Expression?

Don't assume which tool you must use; instead, ask how best the problem
can be solved.

In the case of parsing HTML, regular expressions are a poor fit
<URL:http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454>
because they're not doing the job of parsing.

Use a parser which better understands HTML, like Beautiful Soup
<URL:https://pypi.python.org/pypi/BeautifulSoup>.

-- 
 \      ?An expert is a man who has made all the mistakes which can be |
  `\                         made in a very narrow field.? ?Niels Bohr |
_o__)                                                                  |
Ben Finney


From ahlusar.ahluwalia at gmail.com  Thu Apr  2 02:08:39 2015
From: ahlusar.ahluwalia at gmail.com (Saran Ahluwalia)
Date: Wed, 1 Apr 2015 20:08:39 -0400
Subject: [Tutor] Question for Strategy for Directory Monitor
Message-ID: <CAC9q6M6__PDzeUvQKcj5AwE=xPLL1ZnhXYU2BpKfBEaxOLS=Kg@mail.gmail.com>

Good Evening :

Here is what I want me program to do:

? *Monitor* a folder for files that are dropped throughout the day

? When a file is dropped in the folder the program should scan the file

o IF all the contents in the file have the same length (let's assume line
length)

o THEN the file should be moved to a "success" folder and a text file
written indicating the total number of records/lines/words processed

o IF the file is empty OR the contents are not all of the same length

o THEN the file should be moved to a "failure" folder and a text file
written indicating the cause for failure (for example: Empty file or line
100 was not the same length as the rest).

I want to thank Martin Brown for his guidance and feedback. I welcome any
and all feedback on the following

import os
import time
import glob
import sys

def initialize_logger(output_dir):
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)

    # create console handler and set level to info
    handler = logging.StreamHandler()
    handler.setLevel(logging.INFO)
    formatter = logging.Formatter("%(levelname)s - %(message)s")
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    # create error file handler and set level to error
    handler = logging.FileHandler(os.path.join(output_dir,
"error.log"),"w", encoding=None, delay="true")
    handler.setLevel(logging.ERROR)
    formatter = logging.Formatter("%(levelname)s - %(message)s")
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    # create debug file handler and set level to debug
    handler = logging.FileHandler(os.path.join(output_dir, "all.log"),"w")
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter("%(levelname)s - %(message)s")
    handler.setFormatter(formatter)
    logger.addHandler(handler)


def main(dirslist):
    while True:
        for file in os.listdir(dirslist) :
        return validate_files(file)
        time.sleep(5)

if __name__ == "__main__":
    main()


*#Helper Functions for the Success and Failure Folder Outcomes,
respectively*

    def file_len(filename):
        with open(filename) as f:
            for i, l in enumerate(f):
                pass
            return i + 1

    def copyFile(src, dest):
        try:
            shutil.copy(src, dest)
        # eg. src and dest are the same file
        except shutil.Error as e:
            print('Error: %s' % e)
        # eg. source or destination doesn't exist
        except IOError as e:
            print('Error: %s' % e.strerror)

def move_to_failure_folder_and_return_error_file():
    os.mkdir('Failure')
    copyFile(filename, 'Failure')
    initialize_logger('rootdir/Failure')
    logging.error("Either this file is empty or the lines")


def move_to_success_folder_and_read(file):
    os.mkdir('Success')
    copyFile(filename, 'Success')
    print("Success", file)
    return file_len()

#This simply checks the file information by name
def fileinfo(file):
    filename = os.path.basename(file)
    rootdir = os.path.dirname(file)
    lastmod = time.ctime(os.path.getmtime(file))
    creation = time.ctime(os.path.getctime(file))
    filesize = os.path.getsize(file)
    return filename, rootdir, lastmod, creation, filesize

if __name__ == '__main__':
   import sys
   validate_files(sys.argv[1:])

I am trying to specifically address the fact that the program does not:

   - Assumes that all filenames come directly from the commandline.  No
   searching of a directory.


   - The present code does not move any files to success or failure
directories (I
   have added functions at the end that could serve as substitutes)


   - The present code doesn't calculate or write to a text file.


   - The present code runs once through the names, and terminates.  It doesn't
   "monitor" anything  - I think that I have added the correct while loop.


   - The present code doesn't check for zero-length files

I have attempted to address these but, as a novice, am not sure what is
best practice.

Sincerely,

Saran

From jnl_public at yahoo.com  Thu Apr  2 08:36:03 2015
From: jnl_public at yahoo.com (J L)
Date: Thu, 2 Apr 2015 06:36:03 +0000 (UTC)
Subject: [Tutor] Command Line Editting: How to improve options?
Message-ID: <767754435.3505039.1427956563329.JavaMail.yahoo@mail.yahoo.com>

?Win 7Python v 3.4.3
I'm new to Python and only have coursework under my belt in another object oriented programming language as well as limited systems skills. 
After launching Python?from the command line with py.exe, it appears that the interrupter starts up fine. I've read on Python.Org's site in a tutorial section that some interrupters offer command line editing beyond simple use of the arrow keys and backspace. It does not appear that my environment is allowing these greater abilities.
How does one afford increased abilities to edit commands within Python's interrupter?
Thank you.

From joe.farro at gmail.com  Thu Apr  2 05:18:21 2015
From: joe.farro at gmail.com (Joe Farro)
Date: Wed, 1 Apr 2015 23:18:21 -0400
Subject: [Tutor] Request review: A DSL for scraping a web page
Message-ID: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>

Hello,

I recently wrote a python package and was wondering if anyone might have
time to review it?

I'm fairly new to python - it's been about 1/2 of my workload at work for
the past year. Any suggestions would be super appreciated.

https://github.com/tiffon/take

https://pypi.python.org/pypi/take


The package implements a DSL that is intended to make web-scraping a bit
more maintainable :)

I generally find my scraping code ends up being rather chaotic with
querying, regex manipulations, conditional processing, conversions, etc.,
ending up being to close together and sometimes interwoven. It's stressful.
The DSL attempts to mitigate this by doing only two things: finding stuff
and saving it as a string. The post-processing is left to be done down the
pipeline. It's almost just a configuration file.

Here is an example that would get the text and URL for every link in a page:

    $ a
        save each: links
            | [href]
                save: url
            | text
                save: link_text


The result would be something along these lines:

    {
        'links': [
            {
                'url': 'http://www.something.com/hm',
                'link_text': 'The text in the link'
            },
            # etc... another dict for each <a> tag
        ]
    }


The hope is that having all the selectors in one place will make them more
manageable and possibly simplify the post-processing.

This is my first go at something along these lines, so any feedback is
welcomed.

Thanks!

Joe

From alan.gauld at btinternet.com  Thu Apr  2 10:10:02 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 02 Apr 2015 09:10:02 +0100
Subject: [Tutor] Command Line Editting: How to improve options?
In-Reply-To: <767754435.3505039.1427956563329.JavaMail.yahoo@mail.yahoo.com>
References: <767754435.3505039.1427956563329.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <mfitgq$evq$1@ger.gmane.org>

On 02/04/15 07:36, J L wrote:
>   Win 7Python v 3.4.3

> After launching Python from the command line with py.exe, it appears that the interrupter starts up fine.

Thats interpreter, not interrupter. It interprets your commands.

> I've read on Python.Org's site in a tutorial section that some interrupters
 > offer command line editing

The easiest way for you to get that is to use IDLE, the development tool 
for Python. There should be a menu entry on your OS to launch
IDLE (sometimes called 'Python GUI').

The IDLE interactive shell allows you to use cut n paste, as well as 
keys such as Alt-UP/DOWN to cycle through history etc.

You can get most of these features in the Windows CMD.exe too but you 
need to set some registry entries. Typing HELP CMD at the OS prompt 
brings up a long page describing the features you can choose to
turn on and how.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Thu Apr  2 10:22:02 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 02 Apr 2015 09:22:02 +0100
Subject: [Tutor] Request review: A DSL for scraping a web page
In-Reply-To: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
Message-ID: <mfiu7b$qd2$1@ger.gmane.org>

On 02/04/15 04:18, Joe Farro wrote:
> Hello,
>
> I recently wrote a python package and was wondering if anyone might have
> time to review it?

This list is for people learning Python and answering questions
about the core language and standard library. I suspect this is
more appropriate to the main python list.

However to make any meaningful comments we would probably need a bit 
more of a specification to know what your module does.

> The package implements a DSL that is intended to make web-scraping a bit
> more maintainable :)

DSL?

> I generally find my scraping code ends up being rather chaotic with
> querying, regex manipulations, conditional processing, conversions, etc.,
> ending up being to close together and sometimes interwoven. It's stressful.

Have you looked at the existing web scraping tools in Python?
There are several to pick from. They all avoid the kind of mess
you describe.

 > The DSL attempts to mitigate this by doing only two things:
 > finding stuff and saving it as a string. The post-processing
 > is left to be done down the pipeline. It's almost just
 > a configuration file.

> Here is an example that would get the text and URL for every link in a page:
>
>      $ a
>          save each: links
>              | [href]
>                  save: url
>              | text
>                  save: link_text

And how is that run?
What is the syntax for the config file?
It is not self evident. The other example on github is no less obscure.
I'm sure it means something to you but it is not obvious.

OK, I see there is much more on the github. Sadly too much for me to 
plough through just now.

> The result would be something along these lines:
>
>      {
>          'links': [
>              {
>                  'url': 'http://www.something.com/hm',
>                  'link_text': 'The text in the link'
>              },
>              # etc... another dict for each <a> tag
>          ]
>      }

This seems straightforward.

> The hope is that having all the selectors in one place will make them more
> manageable and possibly simplify the post-processing.
>
> This is my first go at something along these lines, so any feedback is
> welcomed.

I think the main python list is a better bet for feedback on something 
of this size.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From davea at davea.name  Thu Apr  2 11:50:38 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 02 Apr 2015 05:50:38 -0400
Subject: [Tutor] Request review: A DSL for scraping a web page
In-Reply-To: <mfiu7b$qd2$1@ger.gmane.org>
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
 <mfiu7b$qd2$1@ger.gmane.org>
Message-ID: <551D10EE.1060008@davea.name>

On 04/02/2015 04:22 AM, Alan Gauld wrote:
>
> DSL?
>

This is "Domain Specific Language".  This is a language built around a 
specific problem domain, in order to more easily express problems for 
that domain than the usual general purpose languages.

I was a bit surprised to find few google matches, but here's one:

http://www.pcmag.com/encyclopedia/term/41694/domain-specific-language

and of course

http://en.wikipedia.org/wiki/DSL_(disambiguation)



-- 
DaveA

From alan.gauld at btinternet.com  Thu Apr  2 12:41:02 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 02 Apr 2015 11:41:02 +0100
Subject: [Tutor] Request review: A DSL for scraping a web page
In-Reply-To: <551D10EE.1060008@davea.name>
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
 <mfiu7b$qd2$1@ger.gmane.org> <551D10EE.1060008@davea.name>
Message-ID: <mfj6bu$tsq$1@ger.gmane.org>

On 02/04/15 10:50, Dave Angel wrote:
> On 04/02/2015 04:22 AM, Alan Gauld wrote:
>>
>> DSL?
>
> This is "Domain Specific Language".  This is a language built around a
> specific problem domain,

Ah, Thanks Dave!
I am used to those being called simply "Little languages" after the 
famous Jon Bently ACM article that introduced the concept.

http://c2.com/cgi/wiki?LittleLanguage

DSL especially confused me because we had an in-house language
called that, but it wasn't available outside so I didn't see
how the OP could be using it :-)

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From davea at davea.name  Thu Apr  2 13:09:49 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 02 Apr 2015 07:09:49 -0400
Subject: [Tutor] Request review: A DSL for scraping a web page
In-Reply-To: <mfj6bu$tsq$1@ger.gmane.org>
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
 <mfiu7b$qd2$1@ger.gmane.org> <551D10EE.1060008@davea.name>
 <mfj6bu$tsq$1@ger.gmane.org>
Message-ID: <551D237D.8070100@davea.name>

On 04/02/2015 06:41 AM, Alan Gauld wrote:
> On 02/04/15 10:50, Dave Angel wrote:
>> On 04/02/2015 04:22 AM, Alan Gauld wrote:
>>>
>>> DSL?
>>
>> This is "Domain Specific Language".  This is a language built around a
>> specific problem domain,
>
> Ah, Thanks Dave!
> I am used to those being called simply "Little languages" after the
> famous Jon Bently ACM article that introduced the concept.
>
> http://c2.com/cgi/wiki?LittleLanguage
>
> DSL especially confused me because we had an in-house language
> called that, but it wasn't available outside so I didn't see
> how the OP could be using it :-)
>

Ah, Jon Bentley (notice the extra 'e').  I should dig out my *Pearls 
books, and have a trip down memory lane.  I bet 95% of those are still 
useful, even if they refer to much earlier versions of language(s).

I also should find myself a modern Forth system, and see how that's 
evolved over time.  Years ago I was an observer on the ANSI Forth 
standard, as well as newsletter editor for the local FIG.

-- 
DaveA

From alan.gauld at btinternet.com  Thu Apr  2 13:17:44 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 02 Apr 2015 12:17:44 +0100
Subject: [Tutor] Request review: A DSL for scraping a web page
In-Reply-To: <551D237D.8070100@davea.name>
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
 <mfiu7b$qd2$1@ger.gmane.org> <551D10EE.1060008@davea.name>
 <mfj6bu$tsq$1@ger.gmane.org> <551D237D.8070100@davea.name>
Message-ID: <mfj8gn$2ac$1@ger.gmane.org>

On 02/04/15 12:09, Dave Angel wrote:

> Ah, Jon Bentley (notice the extra 'e').  I should dig out my *Pearls
> books, and have a trip down memory lane.  I bet 95% of those are still
> useful, even if they refer to much earlier versions of language(s).

Yes, the Pearls books should be required reading for all new 
programmers. The lessons are pretty timeless, it's only the
languages that change - and most of his examples seem to be
in a kind of pseudo Pascal dialect rather than real code anyway.

I believe they've been re-released as a single volume now.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From davea at davea.name  Thu Apr  2 13:22:19 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 02 Apr 2015 07:22:19 -0400
Subject: [Tutor] Request review: A DSL for scraping a web page
In-Reply-To: <mfj8gn$2ac$1@ger.gmane.org>
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
 <mfiu7b$qd2$1@ger.gmane.org> <551D10EE.1060008@davea.name>
 <mfj6bu$tsq$1@ger.gmane.org> <551D237D.8070100@davea.name>
 <mfj8gn$2ac$1@ger.gmane.org>
Message-ID: <551D266B.9000800@davea.name>

On 04/02/2015 07:17 AM, Alan Gauld wrote:
> On 02/04/15 12:09, Dave Angel wrote:
>
>> Ah, Jon Bentley (notice the extra 'e').  I should dig out my *Pearls
>> books, and have a trip down memory lane.  I bet 95% of those are still
>> useful, even if they refer to much earlier versions of language(s).
>
> Yes, the Pearls books should be required reading for all new
> programmers. The lessons are pretty timeless, it's only the
> languages that change - and most of his examples seem to be
> in a kind of pseudo Pascal dialect rather than real code anyway.
>
> I believe they've been re-released as a single volume now.
>

There was somewhere in one of the books a list of 'good practice,' 
including an item something like:

Solve the right problem.

There's a world of wisdom in that one alone.

-- 
DaveA

From __peter__ at web.de  Thu Apr  2 13:43:37 2015
From: __peter__ at web.de (Peter Otten)
Date: Thu, 02 Apr 2015 13:43:37 +0200
Subject: [Tutor] Request review: A DSL for scraping a web page
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
Message-ID: <mfja1a$p89$1@ger.gmane.org>

Joe Farro wrote:

> The package implements a DSL that is intended to make web-scraping a bit
> more maintainable :)
> 
> I generally find my scraping code ends up being rather chaotic with
> querying, regex manipulations, conditional processing, conversions, etc.,
> ending up being to close together and sometimes interwoven. It's
> stressful. 

Everything is cleaner than a bunch of regular expressions. It's just that 
sometimes they give results more quickly and as reliable as you can get 
without adding a javascript engine to your script.

> The DSL attempts to mitigate this by doing only two things:
> finding stuff and saving it as a string. The post-processing is left to be
> done down the pipeline. It's almost just a configuration file.
> 
> Here is an example that would get the text and URL for every link in a
> page:
> 
>     $ a
>         save each: links
>             | [href]
>                 save: url
>             | text
>                 save: link_text
> 
> 
> The result would be something along these lines:
> 
>     {
>         'links': [
>             {
>                 'url': 'http://www.something.com/hm',
>                 'link_text': 'The text in the link'
>             },
>             # etc... another dict for each <a> tag
>         ]
>     }
> 

With beautiful soup you could write this

soup = bs4.BeautifulSoup(...)

links = [
    {
        "url": a["href"],
        "link_text": a.text
    }
    for a in soup("a")
]

and for many applications you wouldn't even bother with the intermediate 
data structure.

Can you give a real-world example where your DSL is significantly cleaner 
than the corresponding code using bs4, or lxml.xpath, or lxml.objectify?

> The hope is that having all the selectors in one place will make them more
> manageable and possibly simplify the post-processing.
> 
> This is my first go at something along these lines, so any feedback is
> welcomed.

Your code on github looks good to me (too few docstrings), but like Alan I'm 
not prepared to read it completely. Do you have specific questions?


From steve at pearwood.info  Thu Apr  2 14:07:51 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 2 Apr 2015 23:07:51 +1100
Subject: [Tutor] Command Line Editting: How to improve options?
In-Reply-To: <767754435.3505039.1427956563329.JavaMail.yahoo@mail.yahoo.com>
References: <767754435.3505039.1427956563329.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <20150402120751.GX25453@ando.pearwood.info>

On Thu, Apr 02, 2015 at 06:36:03AM +0000, J L wrote:
> ?Win 7Python v 3.4.3
> I'm new to Python and only have coursework under my belt in another 
> object oriented programming language as well as limited systems 
> skills. After launching Python?from the command line with py.exe, it 
> appears that the interrupter starts up fine. I've read on Python.Org's 
> site in a tutorial section that some interrupters offer command line 
> editing beyond simple use of the arrow keys and backspace. It does not 
> appear that my environment is allowing these greater abilities. How 
> does one afford increased abilities to edit commands within Python's 
> interrupter? Thank you. 


Sadly, Windows does not offer much in the way of powerful interactive 
commands like most Linux shells do. You can try these options:

- try using Python's IDLE:

http://www.google.com.au/search?q=how+to+run+IDLE+python

- Use a commercial third-party IDE ("Integrated Development 
Environment") such as PyCharm, Anaconda or Komodo. Some of them may cost 
money, but they may have free or trial versions.

- Or a third-party editor such as Spyder, if it comes with its own 
interactive shell.

- I can strongly recomment iPython, which is very powerful and includes 
a lot of command-line features that even Linux shells don't:

http://ipython.org/
?
If you've used Mathematica, you may love iPython's "notepad" feature.

Now we start getting to slightly more complex options, which may not 
work, but it would be interesting to try:

- Try installing pyreadline, and see it is will work with Python 3.4. If 
it does, you might be able to convince Python 3.4's rlcompleter module 
to work with it.

- Still if pyreadline works with Python 3.4, you might like my command 
line tab completer and history module rather than the built-in one:

http://code.google.com/p/tabhistory/source/browse/tabhistory.py

I've never tested it on Windows, so I don't know if it will actually 
work or not.


Good luck!



-- 
Steve

From wolfrage8765 at gmail.com  Thu Apr  2 18:18:28 2015
From: wolfrage8765 at gmail.com (WolfRage)
Date: Thu, 02 Apr 2015 12:18:28 -0400
Subject: [Tutor] Functional Programming in Python
Message-ID: <551D6BD4.8030507@gmail.com>

These are just some questions that I have regarding the topic of 
Functional Programming. I am working towards a more functional approach 
to programming but acknowledge that it is far from Functional, 
especially since this is mostly impossible in Python.
Questions:
What are the best practices to create more Functional Python?
What are your thoughts on Functional in Python?
Currently I am re-writing functions to reduce their side effects.
I am also removing the state from objects and putting it into a closure 
type function.
However with callback based systems (GUI) this seemed impossible, so 
instead I am abusing a coroutine to maintain the state of the application.
But is it abuse or does it seem like a good way to handle the callback 
system? The benefit to me at this time is limited, but any errors in 
state are confined to a single location, which is nice.
What do you think about using a coroutine to handle state, how would you 
do it better in a callback based system.
Thank you for your insights.

From ahlusar.ahluwalia at gmail.com  Thu Apr  2 14:28:50 2015
From: ahlusar.ahluwalia at gmail.com (Saran Ahluwalia)
Date: Thu, 2 Apr 2015 08:28:50 -0400
Subject: [Tutor] New to Programming: TypeError: coercing to Unicode: need
 string or buffer, list found
Message-ID: <CAC9q6M5hAJz9GvchfwBvSKGwFFL0WBNzYjotCxJ7rCZpzx47Xw@mail.gmail.com>

Good Morning:

I understand this error message when I run this code. However, I am curious
to know what the most pythonic way is to convert  the list to a string? I
use Python 2.7.

"Traceback (most recent call last):
before = dict([(f, None) for f in os.listdir(dirlist)])
TypeError: coercing to Unicode: need string or buffer, list found"


The sample code that I am trying to run is:

path = "/Users/Desktop/Projects/"
dirlist = os.listdir(path)
before = dict([(f, None) for f in os.listdir(dirlist)])

def main(dirlist):
    while True:
        time.sleep(10) #time between update check
    after = dict([(f, None) for f in os.listdir(dirlist)])
    added = [f for f in after if not f in before]
    if added:
        print('Successfully added new file - ready to validate')
if __name__ == "__main__":
    main()

From joe.farro at gmail.com  Thu Apr  2 16:54:01 2015
From: joe.farro at gmail.com (Joe Farro)
Date: Thu, 2 Apr 2015 14:54:01 +0000 (UTC)
Subject: [Tutor] Request review: A DSL for scraping a web page
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
 <mfiu7b$qd2$1@ger.gmane.org>
Message-ID: <loom.20150402T153935-801@post.gmane.org>

Alan Gauld <alan.gauld <at> btinternet.com> writes:
> DSL?

Good to know the term/acronym is not ubiquitous. I was going for
succinct, possibly too succinct...

> Have you looked at the existing web scraping tools in Python?
> There are several to pick from. They all avoid the kind of mess
> you describe.

I'm familiar with a few of them. I've used beautiful soup, PyQuery,
and cssselect. I got frustrated with my scraping code and wrote the
DSL. It's still in the "proving ground" phase of things. A later post
asked about a real-world sample, I'm going to work something up.

> And how is that run?
> What is the syntax for the config file?
> It is not self evident. The other example on github is no less obscure.
> I'm sure it means something to you but it is not obvious.

> 
> OK, I see there is much more on the github. Sadly too much for me to 
> plough through just now.

Thanks for looking. 

> I think the main python list is a better bet for feedback on something 
> of this size.

I wasn't sure if this was sort of at that level, thanks for the suggestion.





From joe.farro at gmail.com  Thu Apr  2 17:08:22 2015
From: joe.farro at gmail.com (Joe Farro)
Date: Thu, 2 Apr 2015 15:08:22 +0000 (UTC)
Subject: [Tutor] Request review: A DSL for scraping a web page
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
 <mfja1a$p89$1@ger.gmane.org>
Message-ID: <loom.20150402T153703-587@post.gmane.org>

Thanks, Peter.

Peter Otten <__peter__ <at> web.de> writes:

> Can you give a real-world example where your DSL is significantly cleaner 
> than the corresponding code using bs4, or lxml.xpath, or lxml.objectify?

Yes, definitely. Will work something up.
 
> Your code on github looks good to me (too few docstrings), but like Alan I'm 
> not prepared to read it completely. Do you have specific questions?

Well, the questions raised (how is it an upgrade) are great food for thought.
The idea and effort were born from legitimate frustrations, but it's not
exactly battle-tested, yet. I'll work up a few examples (the first to
come, shortly). But, great to know nothing immediately disastrous
jumps out in the code. I do have specific questions, but first I want
to work up the use-case, if that looks weak, the other concerns
might be a non-issue.


From alan.gauld at btinternet.com  Thu Apr  2 19:07:18 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 02 Apr 2015 18:07:18 +0100
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <551D6BD4.8030507@gmail.com>
References: <551D6BD4.8030507@gmail.com>
Message-ID: <mfjt06$bbq$1@ger.gmane.org>

On 02/04/15 17:18, WolfRage wrote:

> to programming but acknowledge that it is far from Functional,
> especially since this is mostly impossible in Python.

I'm not sure what you mean is impossible? The specific issues
you are having or the general FP paradigm?

Python has fairly good support for FP, much better than
most non-FP-specific languages.

> Questions:
> What are the best practices to create more Functional Python?

Everything goes in functions which do not change their inputs and return 
outputs.

Use tools like itertools and functools to avoid explicit loops.

> What are your thoughts on Functional in Python?

It's good enough to use where the problem suits FP. It's no
more a pure FP language than it is a pure OOP language.
But in both cases you can get close enough for practical
purposes. What is your problem scenario that makes FP seem
like the best idiom?

> Currently I am re-writing functions to reduce their side effects.

Good, nearly always the best way.

> I am also removing the state from objects and putting it into a closure
> type function.

That may or may not be a good idea. FP object handling can
get awfully messy and awfully inefficient.

> However with callback based systems (GUI) this seemed impossible, so
> instead I am abusing a coroutine to maintain the state of the application.

Trying to force a non-FP framework(eg a GUI)_ to work in an FP
way is usually an exercise in frustration.

> But is it abuse or does it seem like a good way to handle the callback
> system? The benefit to me at this time is limited, but any errors in
> state are confined to a single location, which is nice.

That should be true in an OOP based system too. The whole point
of OOP is to contain and hide state (as opposed to eliminating it)

> What do you think about using a coroutine to handle state, how would you
> do it better in a callback based system.

Without seeing how you are doing it we can't comment on *better*.
We need a baseline. Your approach may be brilliant, or it may
be awful, we can't tell.

But remember that there is no such thing as the perfect paradigm.
FP has many strengths but it has many weaknesses too. As does OOP.
Even procedural programming has advantages over OOP and FP in
some circumstances. By all means learn the paradigms, but don't get hung 
up on any one. They all play a part.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From emile at fenx.com  Thu Apr  2 19:07:16 2015
From: emile at fenx.com (Emile van Sebille)
Date: Thu, 02 Apr 2015 10:07:16 -0700
Subject: [Tutor] Request review: A DSL for scraping a web page
In-Reply-To: <551D266B.9000800@davea.name>
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
 <mfiu7b$qd2$1@ger.gmane.org> <551D10EE.1060008@davea.name>
 <mfj6bu$tsq$1@ger.gmane.org> <551D237D.8070100@davea.name>
 <mfj8gn$2ac$1@ger.gmane.org> <551D266B.9000800@davea.name>
Message-ID: <mfjt1p$5qt$1@ger.gmane.org>

On 4/2/2015 4:22 AM, Dave Angel wrote:
> There was somewhere in one of the books a list of 'good practice,'
> including an item something like:
>
> Solve the right problem.
>
> There's a world of wisdom in that one alone.

+1

Emile



From danny.yoo at gmail.com  Thu Apr  2 19:45:14 2015
From: danny.yoo at gmail.com (Danny Yoo)
Date: Thu, 2 Apr 2015 10:45:14 -0700
Subject: [Tutor] New to Programming: TypeError: coercing to Unicode:
 need string or buffer, list found
In-Reply-To: <CAC9q6M5hAJz9GvchfwBvSKGwFFL0WBNzYjotCxJ7rCZpzx47Xw@mail.gmail.com>
References: <CAC9q6M5hAJz9GvchfwBvSKGwFFL0WBNzYjotCxJ7rCZpzx47Xw@mail.gmail.com>
Message-ID: <CAGZAPF7nRFT45LMaTyG3T20f0LDHgnmrXLgmjCDe70hOufJQvw@mail.gmail.com>

On Apr 2, 2015 9:45 AM, "Saran Ahluwalia" <ahlusar.ahluwalia at gmail.com>
wrote:
>
> Good Morning:
>
> I understand this error message when I run this code. However, I am
curious
> to know what the most pythonic way is to convert  the list to a string? I
> use Python 2.7.
>
> "Traceback (most recent call last):
> before = dict([(f, None) for f in os.listdir(dirlist)])
> TypeError: coercing to Unicode: need string or buffer, list found"

I actually do not understand the error.  :p

In particular, I do not understand the subexpression:

    os.listdir(dirlist)

Can you explain what you are trying to do there?  The listdir function only
consumes single strings, so this looks like a mistake unless dirlist is a
string.

From steve at pearwood.info  Thu Apr  2 20:07:13 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 3 Apr 2015 05:07:13 +1100
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <551D6BD4.8030507@gmail.com>
References: <551D6BD4.8030507@gmail.com>
Message-ID: <20150402180712.GY25453@ando.pearwood.info>

On Thu, Apr 02, 2015 at 12:18:28PM -0400, WolfRage wrote:

> These are just some questions that I have regarding the topic of 
> Functional Programming. I am working towards a more functional approach 
> to programming but acknowledge that it is far from Functional, 
> especially since this is mostly impossible in Python.

It is true that Python is not a purely functional language, like 
Haskell, but that does not stop you from writing code in a functional 
style.


> Questions:
> What are the best practices to create more Functional Python?

Best practices:

* Don't force your code to use one style exclusively. Use the most 
  natural style for the task. Python makes it easy to mix functional, 
  procedural, imperative and object oriented code in the one 
  application. Use whatever is most natural for your task.

* Where possible, write your functions and methods in a functional 
  style. That means:

- Avoid global variables.

- Avoid side-effects where possible.

- Separate the logic of your algorithm from the display of results (e.g. 
  don't have a method that calculates a result AND prints it; have the 
  method calculate the result, and then have the caller print it).

- In Python 3, zip(), map() and filter() are lazy iterator functions; in 
  Python 2 they are eager, but there are lazy versions in the itertools 
  module.

- In Python 3, reduce() is moved to the functools module.

- Many uses of map() and filter() are better written as generator 
  expressions; e.g. instead of:

     filter(lambda s: s.lower().startswith("a"), map(str, mylist))

  you can use:

     (str(x) for x in mylist if s.lower().startswith("a"))


- Where useful, write your code to take advantage of "pipelining" 
  style, e.g. using lazy iterators rather than lists. You can then chain 
  iterators together to get the desired result.


> What are your thoughts on Functional in Python?
> Currently I am re-writing functions to reduce their side effects.
> I am also removing the state from objects and putting it into a closure 
> type function.

That doesn't remove state, it just moves it to a different place.

However, encapsulating state inside a closure, or an object, it often 
the most effective and natural way to deal with a problem. Better than 
passing around long and confusing numbers of variables!


> However with callback based systems (GUI) this seemed impossible, so 
> instead I am abusing a coroutine to maintain the state of the application.
> But is it abuse or does it seem like a good way to handle the callback 
> system? The benefit to me at this time is limited, but any errors in 
> state are confined to a single location, which is nice.
> What do you think about using a coroutine to handle state, how would you 
> do it better in a callback based system.

What do you mean? Can you show an example?


-- 
Steve

From dyoo at hashcollision.org  Thu Apr  2 20:52:40 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Thu, 2 Apr 2015 11:52:40 -0700
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <20150402180712.GY25453@ando.pearwood.info>
References: <551D6BD4.8030507@gmail.com>
 <20150402180712.GY25453@ando.pearwood.info>
Message-ID: <CAGZAPF57iqzyRT6FaB-SbBGmZi_OuXpkVGk8=teTwZJS5+fypA@mail.gmail.com>

>> What are your thoughts on Functional in Python?
>> Currently I am re-writing functions to reduce their side effects.
>> I am also removing the state from objects and putting it into a closure
>> type function.
>
> That doesn't remove state, it just moves it to a different place.
>
> However, encapsulating state inside a closure, or an object, it often
> the most effective and natural way to deal with a problem. Better than
> passing around long and confusing numbers of variables!

Theoretically, I'd agree with this.  But engineering-wise, I'd
recommend explicit structures or objects if possible when representing
state.

Arbitrary lambdas are unconstrained in what they do.  They are raw
material for computation.  You can do pretty much anything with them.
That aspect is often heralded as a positive.  But that means that we
often need to do more work to make lambdas do things that we'd
otherwise do with other built-in features of the language.


Let's make this concrete.  If we want to represent a coordinate, a
pair of numbers, we could use raw closures for this...

################################
def pair(x, y):
    def dispatch(msg):
        if msg == 'x':
             return x
        if msg == 'y':
             return y
    return dispatch

p = pair(3, 4)
print p('x')
print p('y')
################################

And this works!


But there's already a feature in the language that does this kind of
aggregation.

################################
class pair(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

p = pair(3, 4)
print p.x
print p.y
#################################

This is something that folks expect and is well supported and understood.


This is not to say that closures are bad.  It's just to point out that
just because functional programs use closures quite a lot, doesn't
automatically mean closures are the most appropriate tool for
everything.  If there are parts of the language that already do the
sort of thing you're trying to accomplish, it might be good to reuse
those parts, rather than reinvent the universe.

From tim at akwebsoft.com  Thu Apr  2 21:08:27 2015
From: tim at akwebsoft.com (Tim Johnson)
Date: Thu, 2 Apr 2015 11:08:27 -0800
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <551D6BD4.8030507@gmail.com>
References: <551D6BD4.8030507@gmail.com>
Message-ID: <20150402190827.GA5392@mail.akwebsoft.com>

* WolfRage <wolfrage8765 at gmail.com> [150402 08:25]:
> These are just some questions that I have regarding the topic of 
> Functional Programming. I am working towards a more functional approach 
> to programming but acknowledge that it is far from Functional, 
> especially since this is mostly impossible in Python.
> Questions:
> What are the best practices to create more Functional Python?
> What are your thoughts on Functional in Python?
> Currently I am re-writing functions to reduce their side effects.
> I am also removing the state from objects and putting it into a closure 
> type function.
> However with callback based systems (GUI) this seemed impossible, so 
> instead I am abusing a coroutine to maintain the state of the application.
> But is it abuse or does it seem like a good way to handle the callback 
> system? The benefit to me at this time is limited, but any errors in 
> state are confined to a single location, which is nice.
> What do you think about using a coroutine to handle state, how would you 
> do it better in a callback based system.
> Thank you for your insights.
  You have already received valuable replies from two advanced
  python experts. 
  If you are looking for a book (available digitally for kindle)
  I would recommend 
  Guide To: Functional Python & Comprehension Constructs 
    by Matt Harrison
-- 
Tim 
tim at tee jay forty nine dot com or akwebsoft dot com
http://www.akwebsoft.com, http://www.tj49.com

From wolfrage8765 at gmail.com  Thu Apr  2 21:26:53 2015
From: wolfrage8765 at gmail.com (WolfRage)
Date: Thu, 02 Apr 2015 15:26:53 -0400
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <mfjt06$bbq$1@ger.gmane.org>
References: <551D6BD4.8030507@gmail.com> <mfjt06$bbq$1@ger.gmane.org>
Message-ID: <551D97FD.2030009@gmail.com>

On 04/02/2015 01:07 PM, Alan Gauld wrote:
<SNIP>
> I'm not sure what you mean is impossible? The specific issues
> you are having or the general FP paradigm?
I mean achieving truely functional code, atleast to the extent of some 
of the things that I have read. But in general I do not need nor want 
any of those special features. I.E. single assignment, optimized tail 
call, etc.
>
> Python has fairly good support for FP, much better than
> most non-FP-specific languages.
I agree.
<SNIP>
> Everything goes in functions which do not change their inputs and return
> outputs.
I am getting better at this.
>
> Use tools like itertools and functools to avoid explicit loops.
I am beginning to use them more.
>
>> What are your thoughts on Functional in Python?
>
> It's good enough to use where the problem suits FP. It's no
> more a pure FP language than it is a pure OOP language.
> But in both cases you can get close enough for practical
> purposes. What is your problem scenario that makes FP seem
> like the best idiom?
Since I am making a game, three things got out of control.
1. Managing transitions and instances of objects between transitions. 
Like loading the Main Menu then starting a Game, then returning to the 
Menu and Starting a New Game, the old game was still hanging around in 
memory which becomes a problem on Phones.
2. Side effects have gotten out of hand, and so adding a feature often 
meant adding bugs.
3. Duplication of code got out of hand. Several functions doing similar 
things but slightly different. I turned this into pipe-lining to reduce 
out the different cases and eliminate the duplication.

But since it is a game the amount of state does make FP seem very 
difficult and thus the game is a mixture of OOP and FP, which I am glad 
to see people saying mix as needed.
>
>> Currently I am re-writing functions to reduce their side effects.
>
> Good, nearly always the best way.
>
>> I am also removing the state from objects and putting it into a closure
>> type function.
>
> That may or may not be a good idea. FP object handling can
> get awfully messy and awfully inefficient.
>
>> However with callback based systems (GUI) this seemed impossible, so
>> instead I am abusing a coroutine to maintain the state of the
>> application.
>
> Trying to force a non-FP framework(eg a GUI)_ to work in an FP
> way is usually an exercise in frustration.
Yeah, it took me awhile to think about what to do in this case. Thus I 
decided it was best to accept that the interface between the GUI and my 
code had to be more OOP.
>
>> But is it abuse or does it seem like a good way to handle the callback
>> system? The benefit to me at this time is limited, but any errors in
>> state are confined to a single location, which is nice.
>
> That should be true in an OOP based system too. The whole point
> of OOP is to contain and hide state (as opposed to eliminating it)
I think since I am mostly self taught I perhaps failed to learn this 
containment of state until recently. So before now it was fairly common 
for my state to be spread out amongst several objects. It seems hard for 
me to contain state in a OOP manor, just because it is so easy to use self.
>
>> What do you think about using a coroutine to handle state, how would you
>> do it better in a callback based system.
>
> Without seeing how you are doing it we can't comment on *better*.
> We need a baseline. Your approach may be brilliant, or it may
> be awful, we can't tell.
Yeah probably not brilliant. More like hopefully not completely stupid.
>
> But remember that there is no such thing as the perfect paradigm.
> FP has many strengths but it has many weaknesses too. As does OOP.
> Even procedural programming has advantages over OOP and FP in
> some circumstances. By all means learn the paradigms, but don't get hung
> up on any one. They all play a part.
Agreed. I am still trying to learn the right mixture.

The GUI is Kivy, but I could probably apply the same concept to QT.
Example of my Abused coroutine:

def coroutine(func):
     # A decorator function that takes care of starting a coroutine
     # automatically on call.
     def start(*args, **kwargs):
         cr = func(*args, **kwargs)
         cr.send(None)
         return cr
     return start


@coroutine
def app_state(APP):
     # APP = kivy.app.App.get_running_app()  # So you know what APP is.
     while True:
         signal = yield
         # Pass if signal is None or less than 1.
         if signal >= 0 and signal < 1:
             pass  # Ignore this range
         elif signal >= 1 and signal < 2:
             if signal == 1.01:  # Load Main Menu
                 print('Load File for Displaying Main Menu')
                 # This acts as a callback with the benefit of yielding
                 # to Kivy's main loop.
                 kivy.clock.Clock.schedule_once(APP.signal, 0)
                 yield 1.02
                 print('Add Main Menu to ScreenManager.')
                 kivy.clock.Clock.schedule_once(APP.signal, 0)
                 yield 1.03
                 print('Start Music for Main Menu')
                 # Other clean up that I do here.
                 # Remove Game from Screen Manager
                 # Delete References to Game
         elif signal >= 2 and signal < 3:
             if signal == 2.01:
                 print('Load File for Displaying Game')
                 kivy.clock.Clock.schedule_once(APP.signal, 0)
                 yield 2.02
                 print('Add Game to ScreenManager.')
                 kivy.clock.Clock.schedule_once(APP.signal, 0)
                 yield 2.03
                 print('Start Music for Main Menu')
                 # Other clean up that I do here.
                 # Remove Main Menu from Screen Manager
                 # Delete References to Main Menu

state = app_state(kivy.app.App.get_running_app())
kivy.app.App.get_running_app().signal = state.send



From danny.yoo at gmail.com  Thu Apr  2 21:31:11 2015
From: danny.yoo at gmail.com (Danny Yoo)
Date: Thu, 2 Apr 2015 12:31:11 -0700
Subject: [Tutor] New to Programming: TypeError: coercing to Unicode:
 need string or buffer, list found
In-Reply-To: <CAC9q6M44ksb2XnHVedq-3Jq1qAoaoXVZ7uz-GxJQTHA6tvaTtg@mail.gmail.com>
References: <CAC9q6M5hAJz9GvchfwBvSKGwFFL0WBNzYjotCxJ7rCZpzx47Xw@mail.gmail.com>
 <CAGZAPF7nRFT45LMaTyG3T20f0LDHgnmrXLgmjCDe70hOufJQvw@mail.gmail.com>
 <CAC9q6M44ksb2XnHVedq-3Jq1qAoaoXVZ7uz-GxJQTHA6tvaTtg@mail.gmail.com>
Message-ID: <CAGZAPF5V35W+d-ZOjrVHuLhQPm16ebskN5WvHwv9UrufDi_j8Q@mail.gmail.com>

On Thu, Apr 2, 2015 at 12:19 PM, Saran Ahluwalia
<ahlusar.ahluwalia at gmail.com> wrote:
> Danny,
>
> You were spot on with that issue. I debugged this. Here are my two commits
> for my homework: Starting with pyinotify and OS agnostic? I am still working
> on the latter - in regards to adding more customization that fits the
> homework specifications.

As a high-level thing: when you see an error message, do not
automatically assume the error message knows the proper remediation.


Revisit the error message and your initial instincts:

#####################################################################
TypeError: coercing to Unicode: need string or buffer, list found"

> I understand this error message when I run this code. However, I am curious
> to know what the most pythonic way is to convert  the list to a string?
#####################################################################

And in retrospect, hopefully you'll see that the correct thing to do
was something other than what you thought at first.  In programming,
when things go wrong, they can go wrong for several different reasons.


There is research that suggests that beginners often misinterpret a
course of actions when reading error messages.
http://gmarceau.qc.ca/papers/Marceau-2010-Measuring-Effectiveness.pdf
So try to avoid the temptation to only do something that makes the
computer happy.  Revisit assumptions.


Good luck!

From wolfrage8765 at gmail.com  Thu Apr  2 21:36:17 2015
From: wolfrage8765 at gmail.com (WolfRage)
Date: Thu, 02 Apr 2015 15:36:17 -0400
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <20150402180712.GY25453@ando.pearwood.info>
References: <551D6BD4.8030507@gmail.com>
 <20150402180712.GY25453@ando.pearwood.info>
Message-ID: <551D9A31.3040509@gmail.com>

On 04/02/2015 02:07 PM, Steven D'Aprano wrote:
<SNIP>
>> What are the best practices to create more Functional Python?
>
> Best practices:
>
> * Don't force your code to use one style exclusively. Use the most
>    natural style for the task. Python makes it easy to mix functional,
>    procedural, imperative and object oriented code in the one
>    application. Use whatever is most natural for your task.
Good point, but still trying to understand how this is best determined 
beyond trial and error, and to make sure that my assumptions are correct 
about this decision.
>
> * Where possible, write your functions and methods in a functional
>    style. That means:
>
> - Avoid global variables.
I have got this down.
>
> - Avoid side-effects where possible.
Now getting better at this.
>
> - Separate the logic of your algorithm from the display of results (e.g.
>    don't have a method that calculates a result AND prints it; have the
>    method calculate the result, and then have the caller print it).
Need to always do this and do it first rather than during re-factoring.
>
<SNIP>
>
> - Many uses of map() and filter() are better written as generator
>    expressions; e.g. instead of:
I now understand generators and I am now using them whenever I see the 
opportunity.
>
>       filter(lambda s: s.lower().startswith("a"), map(str, mylist))
>
>    you can use:
>
>       (str(x) for x in mylist if s.lower().startswith("a"))
>
>
> - Where useful, write your code to take advantage of "pipelining"
>    style, e.g. using lazy iterators rather than lists. You can then chain
>    iterators together to get the desired result.
Yes I have started to do this since seeing the power of pipe-lining.
<SNIP>
> What do you mean? Can you show an example?
I added an example in the reply to Alan.

From wolfrage8765 at gmail.com  Thu Apr  2 21:39:24 2015
From: wolfrage8765 at gmail.com (WolfRage)
Date: Thu, 02 Apr 2015 15:39:24 -0400
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <CAGZAPF57iqzyRT6FaB-SbBGmZi_OuXpkVGk8=teTwZJS5+fypA@mail.gmail.com>
References: <551D6BD4.8030507@gmail.com>
 <20150402180712.GY25453@ando.pearwood.info>
 <CAGZAPF57iqzyRT6FaB-SbBGmZi_OuXpkVGk8=teTwZJS5+fypA@mail.gmail.com>
Message-ID: <551D9AEC.3050108@gmail.com>

On 04/02/2015 02:52 PM, Danny Yoo wrote:
<SNIP>
> This is not to say that closures are bad.  It's just to point out that
> just because functional programs use closures quite a lot, doesn't
> automatically mean closures are the most appropriate tool for
> everything.  If there are parts of the language that already do the
> sort of thing you're trying to accomplish, it might be good to reuse
> those parts, rather than reinvent the universe.
I agree that closures are not the best tool for every job. And in the 
case of a callback based GUI they simply do not work, since execution 
needs to leave a function in order to run the GUI's main loop. Thus I 
abused a coroutine.


From wolfrage8765 at gmail.com  Thu Apr  2 21:40:28 2015
From: wolfrage8765 at gmail.com (WolfRage)
Date: Thu, 02 Apr 2015 15:40:28 -0400
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <20150402190827.GA5392@mail.akwebsoft.com>
References: <551D6BD4.8030507@gmail.com>
 <20150402190827.GA5392@mail.akwebsoft.com>
Message-ID: <551D9B2C.8080401@gmail.com>

On 04/02/2015 03:08 PM, Tim Johnson wrote:
<SNIP>
>    You have already received valuable replies from two advanced
>    python experts.
>    If you are looking for a book (available digitally for kindle)
>    I would recommend
>    Guide To: Functional Python & Comprehension Constructs
>      by Matt Harrison
Thanks I will look into this book. I have been reading a lot of articles 
on the topic lately.


From fomcl at yahoo.com  Thu Apr  2 21:49:45 2015
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Thu, 2 Apr 2015 12:49:45 -0700
Subject: [Tutor] Request review: A DSL for scraping a web page
Message-ID: <1428004185.39042.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>


-----------------------------
On Thu, Apr 2, 2015 1:17 PM CEST Alan Gauld wrote:

>On 02/04/15 12:09, Dave Angel wrote:
>
>> Ah, Jon Bentley (notice the extra 'e').  I should dig out my *Pearls
>> books, and have a trip down memory lane.  I bet 95% of those are still
>> useful, even if they refer to much earlier versions of language(s).
>
>Yes, the Pearls books should be required reading for all new programmers. The lessons are pretty timeless, it's only the
>languages that change - and most of his examples seem to be
>in a kind of pseudo Pascal dialect rather than real code anyway.
>
>I believe they've been re-released as a single volume now.

Is this the book you are referring to? 
http://www.amazon.com/Programming-Pearls-2nd-Edition-Bentley/dp/0201657880

Thanks!

From davea at davea.name  Thu Apr  2 22:18:52 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 02 Apr 2015 16:18:52 -0400
Subject: [Tutor] New to Programming: TypeError: coercing to Unicode:
 need string or buffer, list found
In-Reply-To: <CAC9q6M5hAJz9GvchfwBvSKGwFFL0WBNzYjotCxJ7rCZpzx47Xw@mail.gmail.com>
References: <CAC9q6M5hAJz9GvchfwBvSKGwFFL0WBNzYjotCxJ7rCZpzx47Xw@mail.gmail.com>
Message-ID: <551DA42C.4040302@davea.name>

On 04/02/2015 08:28 AM, Saran Ahluwalia wrote:
> Good Morning:
>
> I understand this error message when I run this code. However, I am curious
> to know what the most pythonic way is to convert  the list to a string? I
> use Python 2.7.
>
> "Traceback (most recent call last):
> before = dict([(f, None) for f in os.listdir(dirlist)])
> TypeError: coercing to Unicode: need string or buffer, list found"
>

 >
 > The sample code that I am trying to run is:
 >
 > path = "/Users/Desktop/Projects/"
 > dirlist = os.listdir(path)
 > before = dict([(f, None) for f in os.listdir(dirlist)])


You have two calls to listdir in the code you quote here.  Once you've 
called os.listdir(path)  you get back a list of filenames.  Why you then 
call os.listdir again on that list I have no clue.  And I also have no 
idea what you think the dict is going to do.


>
> def main(dirlist):
>      while True:
>          time.sleep(10) #time between update check
>      after = dict([(f, None) for f in os.listdir(dirlist)])
>      added = [f for f in after if not f in before]
>      if added:
>          print('Successfully added new file - ready to validate')
> if __name__ == "__main__":
>      main()

You didn't run that code, as this call to main() passes no arguments. 
Last time I saw your whole file, it had two separate  if __name__ == 
"__main__" clauses.  So you'd better make sure one of them is commented 
out, or it'll keep confusing you.

First thing is to pick better names.  And second is to add a comment to 
each function as to what it expects for arguments.  main() expects a 
directory name, so rename the dirlist variable to something like path.

Then figure out what the argument to main() should look like.  it should 
not be  sys.argv[1:], as that's a list.  You want a single item on the 
command line specifying the path.


This whole thing with 'before' and 'after' is the long way around. 
Since you're going to move files from this directory after you analyze 
them, all you need to do is call os.listdir again each time through the 
loop.  Anything you find will be new, by definition.

Then once you have your list, you do NOT want to loop through it, as 
you're going to be calling a function (already written by you) that 
wants a list of filenames.

Incidentally you posted some code earlier, in yet another new thread, 
that calls copyfile() from the function move_to_failure_folder(). 
Shouldn't that function be called movefile()?  and shouldn't it use a 
different shutil function?

-- 
DaveA

From davea at davea.name  Thu Apr  2 22:42:56 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 02 Apr 2015 16:42:56 -0400
Subject: [Tutor] Request review: A DSL for scraping a web page
In-Reply-To: <1428004185.39042.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
References: <1428004185.39042.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
Message-ID: <551DA9D0.4010802@davea.name>

On 04/02/2015 03:49 PM, Albert-Jan Roskam wrote:
>
> -----------------------------
> On Thu, Apr 2, 2015 1:17 PM CEST Alan Gauld wrote:
>
>> On 02/04/15 12:09, Dave Angel wrote:
>>
>>> Ah, Jon Bentley (notice the extra 'e').  I should dig out my *Pearls
>>> books, and have a trip down memory lane.  I bet 95% of those are still
>>> useful, even if they refer to much earlier versions of language(s).
>>
>> Yes, the Pearls books should be required reading for all new programmers. The lessons are pretty timeless, it's only the
>> languages that change - and most of his examples seem to be
>> in a kind of pseudo Pascal dialect rather than real code anyway.
>>
>> I believe they've been re-released as a single volume now.
>
> Is this the book you are referring to?
> http://www.amazon.com/Programming-Pearls-2nd-Edition-Bentley/dp/0201657880
>
> Thanks!

That is a new edition of "Programming Pearls", but I can't tell from its 
description if it also includes "More Programming Pearls: Confessions of 
a Coder"

If the two were merged, I don't spot it any place on Amazon.

-- 
DaveA

From alan.gauld at btinternet.com  Thu Apr  2 23:02:51 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 02 Apr 2015 22:02:51 +0100
Subject: [Tutor] Request review: A DSL for scraping a web page
In-Reply-To: <1428004185.39042.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
References: <1428004185.39042.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
Message-ID: <551DAE7B.3010803@btinternet.com>

On 02/04/15 20:49, Albert-Jan Roskam wrote:
> Yes, the Pearls books should be required reading

> Is this the book you are referring to?
> http://www.amazon.com/Programming-Pearls-2nd-Edition-Bentley/dp/0201657880
>

Yes thats it.


> -- 
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>

From ahlusar.ahluwalia at gmail.com  Thu Apr  2 21:19:55 2015
From: ahlusar.ahluwalia at gmail.com (Saran Ahluwalia)
Date: Thu, 2 Apr 2015 15:19:55 -0400
Subject: [Tutor] New to Programming: TypeError: coercing to Unicode:
 need string or buffer, list found
In-Reply-To: <CAGZAPF7nRFT45LMaTyG3T20f0LDHgnmrXLgmjCDe70hOufJQvw@mail.gmail.com>
References: <CAC9q6M5hAJz9GvchfwBvSKGwFFL0WBNzYjotCxJ7rCZpzx47Xw@mail.gmail.com>
 <CAGZAPF7nRFT45LMaTyG3T20f0LDHgnmrXLgmjCDe70hOufJQvw@mail.gmail.com>
Message-ID: <CAC9q6M44ksb2XnHVedq-3Jq1qAoaoXVZ7uz-GxJQTHA6tvaTtg@mail.gmail.com>

Danny,

You were spot on with that issue. I debugged this. Here are my two commits
for my homework: Starting with pyinotify
<https://github.com/ahlusar1989/WGProjects/blob/master/pyinotifyWGrun.py>
 and OS agnostic?
<https://github.com/ahlusar1989/WGProjects/commit/b8a2de25d45b1dc02b1dc189d2cfb71683fbdd9a?diff=unified#diff-0700a6bf321f99757963c11d7866aea4>
I
am still working on the latter - in regards to adding more customization
that fits the homework specifications.

Feel free to shoot me any critical feedback - when you can.

Cheers:

Saran

On Thu, Apr 2, 2015 at 1:45 PM, Danny Yoo <danny.yoo at gmail.com> wrote:

>
> On Apr 2, 2015 9:45 AM, "Saran Ahluwalia" <ahlusar.ahluwalia at gmail.com>
> wrote:
> >
> > Good Morning:
> >
> > I understand this error message when I run this code. However, I am
> curious
> > to know what the most pythonic way is to convert  the list to a string? I
> > use Python 2.7.
> >
> > "Traceback (most recent call last):
> > before = dict([(f, None) for f in os.listdir(dirlist)])
> > TypeError: coercing to Unicode: need string or buffer, list found"
>
> I actually do not understand the error.  :p
>
> In particular, I do not understand the subexpression:
>
>     os.listdir(dirlist)
>
> Can you explain what you are trying to do there?  The listdir function
> only consumes single strings, so this looks like a mistake unless dirlist
> is a string.
>

From tim at akwebsoft.com  Fri Apr  3 02:10:44 2015
From: tim at akwebsoft.com (Tim Johnson)
Date: Thu, 2 Apr 2015 16:10:44 -0800
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <551D9B2C.8080401@gmail.com>
References: <551D6BD4.8030507@gmail.com>
 <20150402190827.GA5392@mail.akwebsoft.com> <551D9B2C.8080401@gmail.com>
Message-ID: <20150403001044.GA1757@mail.akwebsoft.com>

* WolfRage <wolfrage8765 at gmail.com> [150402 11:45]:
> On 04/02/2015 03:08 PM, Tim Johnson wrote:
> <SNIP>
> >   You have already received valuable replies from two advanced
> >   python experts.
> >   If you are looking for a book (available digitally for kindle)
> >   I would recommend
> >   Guide To: Functional Python & Comprehension Constructs
> >     by Matt Harrison
> Thanks I will look into this book. I have been reading a lot of articles 
> on the topic lately.
  Harrison really focuses on List Comprehension as the idiomatic
  pythonist approach. He's very clear and concise as this eternal
  noob can readily understand him. I hope you find it edifying.

-- 
Tim 
tim at tee jay forty nine dot com or akwebsoft dot com
http://www.akwebsoft.com, http://www.tj49.com

From jnl_public at yahoo.com  Fri Apr  3 01:02:26 2015
From: jnl_public at yahoo.com (J L)
Date: Thu, 2 Apr 2015 23:02:26 +0000 (UTC)
Subject: [Tutor] Command Line Editting: How to improve options?
In-Reply-To: <20150402120751.GX25453@ando.pearwood.info>
References: <20150402120751.GX25453@ando.pearwood.info>
Message-ID: <1595076443.4131028.1428015746150.JavaMail.yahoo@mail.yahoo.com>

Thank you Steve.?


This electronic mail including any attachments may contain information that is privileged, confidential, and/or otherwise protected from disclosure to anyone other than its intended recipient(s). Any dissemination of this electronic email or its contents including any attachments is prohibited without prior consent.
 


     On Thursday, April 2, 2015 5:09 AM, Steven D'Aprano <steve at pearwood.info> wrote:
   

 On Thu, Apr 02, 2015 at 06:36:03AM +0000, J L wrote:
> ?Win 7Python v 3.4.3
> I'm new to Python and only have coursework under my belt in another 
> object oriented programming language as well as limited systems 
> skills. After launching Python?from the command line with py.exe, it 
> appears that the interrupter starts up fine. I've read on Python.Org's 
> site in a tutorial section that some interrupters offer command line 
> editing beyond simple use of the arrow keys and backspace. It does not 
> appear that my environment is allowing these greater abilities. How 
> does one afford increased abilities to edit commands within Python's 
> interrupter? Thank you. 


Sadly, Windows does not offer much in the way of powerful interactive 
commands like most Linux shells do. You can try these options:

- try using Python's IDLE:

http://www.google.com.au/search?q=how+to+run+IDLE+python

- Use a commercial third-party IDE ("Integrated Development 
Environment") such as PyCharm, Anaconda or Komodo. Some of them may cost 
money, but they may have free or trial versions.

- Or a third-party editor such as Spyder, if it comes with its own 
interactive shell.

- I can strongly recomment iPython, which is very powerful and includes 
a lot of command-line features that even Linux shells don't:

http://ipython.org/
?
If you've used Mathematica, you may love iPython's "notepad" feature.

Now we start getting to slightly more complex options, which may not 
work, but it would be interesting to try:

- Try installing pyreadline, and see it is will work with Python 3.4. If 
it does, you might be able to convince Python 3.4's rlcompleter module 
to work with it.

- Still if pyreadline works with Python 3.4, you might like my command 
line tab completer and history module rather than the built-in one:

http://code.google.com/p/tabhistory/source/browse/tabhistory.py

I've never tested it on Windows, so I don't know if it will actually 
work or not.


Good luck!



-- 
Steve
_______________________________________________
Tutor maillist? -? Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


  

From akleider at sonic.net  Fri Apr  3 02:29:57 2015
From: akleider at sonic.net (Alex Kleider)
Date: Thu, 02 Apr 2015 17:29:57 -0700
Subject: [Tutor] python3.4m
Message-ID: <2a8173b7079ef94a3a08c2203cedd052@sonic.net>

A listing of /usr/bin/python* on my Ubuntu 14.04 LTS machine yields the 
following:
alex at t61p:~$ ls -l /usr/bin/python*
lrwxrwxrwx 1 root root       9 Aug 23  2014 /usr/bin/python -> python2.7
lrwxrwxrwx 1 root root       9 Aug 23  2014 /usr/bin/python2 -> 
python2.7
-rwxr-xr-x 1 root root 3176896 Mar 22  2014 /usr/bin/python2.7
lrwxrwxrwx 1 root root       9 Aug 23  2014 /usr/bin/python3 -> 
python3.4
-rwxr-xr-x 1 root root 3802224 Apr 11  2014 /usr/bin/python3.4
-rwxr-xr-x 1 root root 3802224 Apr 11  2014 /usr/bin/python3.4m
lrwxrwxrwx 1 root root      10 Aug 23  2014 /usr/bin/python3m -> 
python3.4m

What is python3.4m?
When might one want it instead of python3.4 without the 'm'?

thanks,
Alex


From ben+python at benfinney.id.au  Fri Apr  3 04:42:31 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Fri, 03 Apr 2015 13:42:31 +1100
Subject: [Tutor] python3.4m
References: <2a8173b7079ef94a3a08c2203cedd052@sonic.net>
Message-ID: <85fv8i0w6g.fsf@benfinney.id.au>

Alex Kleider <akleider at sonic.net> writes:

> A listing of /usr/bin/python* on my Ubuntu 14.04 LTS machine yields
> the following:
> alex at t61p:~$ ls -l /usr/bin/python*
> [?]
> -rwxr-xr-x 1 root root 3802224 Apr 11  2014 /usr/bin/python3.4m
> lrwxrwxrwx 1 root root      10 Aug 23  2014 /usr/bin/python3m -> 
> python3.4m
>
> What is python3.4m?

I can't tell you what it is. I can, though, tell you how to query what
package installed it::

    $ dpkg --search /usr/bin/python3.4m

which might give some useful information.

-- 
 \       ?Whenever you read a good book, it's like the author is right |
  `\   there, in the room talking to you, which is why I don't like to |
_o__)                                   read good books.? ?Jack Handey |
Ben Finney


From steve at pearwood.info  Fri Apr  3 05:23:31 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 3 Apr 2015 14:23:31 +1100
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <551D9A31.3040509@gmail.com>
References: <551D6BD4.8030507@gmail.com>
 <20150402180712.GY25453@ando.pearwood.info> <551D9A31.3040509@gmail.com>
Message-ID: <20150403032331.GB25453@ando.pearwood.info>

On Thu, Apr 02, 2015 at 03:36:17PM -0400, WolfRage wrote:
> On 04/02/2015 02:07 PM, Steven D'Aprano wrote:
> <SNIP>
> >>What are the best practices to create more Functional Python?
> >
> >Best practices:
> >
> >* Don't force your code to use one style exclusively. Use the most
> >   natural style for the task. Python makes it easy to mix functional,
> >   procedural, imperative and object oriented code in the one
> >   application. Use whatever is most natural for your task.
>
> Good point, but still trying to understand how this is best determined 
> beyond trial and error, and to make sure that my assumptions are correct 
> about this decision.

Practice and experience!



> >* Where possible, write your functions and methods in a functional
> >   style. That means:
> >
> >- Avoid global variables.
>
> I have got this down.

Just for the record, not all use of globals is bad. In my previous 
reply to Danny, I gave an example of "late binding" for a default 
parameter. In general, global constants, or near constants (e.g. you 
write to the variable once when your application starts up, perhaps 
after reading the value from a config file) are acceptable.

> >- Avoid side-effects where possible.
>
> Now getting better at this.

In object-oriented code, "side-effects" of course refers to side-effects 
outside of the object itself. An object is allowed to manipulate its own 
state.

However, even in OO code, it is very useful to avoid side-effects. For 
example, the object might be immutable, so once it is initialised it 
cannot be changed. Even if your object is mutable, you should cleanly 
separate mutator methods which can modify the object from side-effect 
free methods which do not.

E.g. it is okay for list.sort() to mutate the list, but list.index() 
should not!


-- 
Steve

From steve at pearwood.info  Fri Apr  3 05:07:02 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 3 Apr 2015 14:07:02 +1100
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <CAGZAPF57iqzyRT6FaB-SbBGmZi_OuXpkVGk8=teTwZJS5+fypA@mail.gmail.com>
References: <551D6BD4.8030507@gmail.com>
 <20150402180712.GY25453@ando.pearwood.info>
 <CAGZAPF57iqzyRT6FaB-SbBGmZi_OuXpkVGk8=teTwZJS5+fypA@mail.gmail.com>
Message-ID: <20150403030702.GA25453@ando.pearwood.info>

On Thu, Apr 02, 2015 at 11:52:40AM -0700, Danny Yoo wrote:
> >> What are your thoughts on Functional in Python?
> >> Currently I am re-writing functions to reduce their side effects.
> >> I am also removing the state from objects and putting it into a closure
> >> type function.
> >
> > That doesn't remove state, it just moves it to a different place.
> >
> > However, encapsulating state inside a closure, or an object, it often
> > the most effective and natural way to deal with a problem. Better than
> > passing around long and confusing numbers of variables!
> 
> Theoretically, I'd agree with this.  But engineering-wise, I'd
> recommend explicit structures or objects if possible when representing
> state.

Yes, I agree! Hence my comment about encapsulating state inside a 
closure *or an object* rather than keeping your application state in 
your head, passing around vast numbers of variables only because some 
other part of your application needs them...

[...]
> Let's make this concrete.  If we want to represent a coordinate, a
> pair of numbers, we could use raw closures for this...
> 
> ################################
> def pair(x, y):
>     def dispatch(msg):
>         if msg == 'x':
>              return x
>         if msg == 'y':
>              return y
>     return dispatch
> 
> p = pair(3, 4)
> print p('x')
> print p('y')
> ################################
> 
> And this works!
> 
> 
> But there's already a feature in the language that does this kind of
> aggregation.
> 
> ################################
> class pair(object):
>     def __init__(self, x, y):
>         self.x, self.y = x, y
> 
> p = pair(3, 4)
> print p.x
> print p.y
> #################################
> 
> This is something that folks expect and is well supported and understood.

Precisely. I was thinking more along the idea of using closures, or 
functools.partial, for encapsulating state in this way. Suppose we start 
with two global variables:

def greet():
    print "%s, %s!"  % (greeting, name)

greeting = "Salutations"
name = "Danny"

greet()


Yuck. The obvious fix is to turn the globals into parameters:

def greet(greeting, name):
    print "%s, %s!"  % (greeting, name)

and pass in the greeting and name you need. And for many purposes that 
is exactly the solution you need.

But... sometimes you don't want to have to manually keep track of this 
"greeting" variable just for the sake of passing it on to the greet() 
function. There are lots of solutions to that problem:

# Early binding default value.
def greet(name, greeting="Salutations"):
    print "%s, %s!"  % (greeting, name)

# Late binding default value.
GREETING = "Salutations"
def greet(name, greeting=None):
    if greeting is None:
        greeting = GREETING
    print "%s, %s!"  % (greeting, name)

# An object is overkill, but let's do it anyway
class Greeter:
    def __init__(self, greeting):
        self.greeting = greeting
    def greet(self, name):
        print "%s, %s!"  % (self.greeting, name)

mygreeter = Greeter("Salutations")
mygreeter.greet("Danny")


Or we can use a closure:

def make_greeter(greeting):
    def greet(name):
        print "%s, %s!"  % (greeting, name)
    return greet

greet = make_greeter("Salutations")
greet("Danny")



> This is not to say that closures are bad.  It's just to point out that
> just because functional programs use closures quite a lot, doesn't
> automatically mean closures are the most appropriate tool for
> everything.  If there are parts of the language that already do the
> sort of thing you're trying to accomplish, it might be good to reuse
> those parts, rather than reinvent the universe.

Agreed.

That's the beauty of Python: you can mix paradigms in the one piece of 
code. The downside of this is that it reduces the opportunities for many 
compile-time optimizations (e.g. the compiler cannot know for sure that 
any function is free of side-effects) but that's often an acceptable 
price to pay.

-- 
Steve

From akleider at sonic.net  Fri Apr  3 06:35:49 2015
From: akleider at sonic.net (Alex Kleider)
Date: Thu, 02 Apr 2015 21:35:49 -0700
Subject: [Tutor] python3.4m
In-Reply-To: <85fv8i0w6g.fsf@benfinney.id.au>
References: <2a8173b7079ef94a3a08c2203cedd052@sonic.net>
 <85fv8i0w6g.fsf@benfinney.id.au>
Message-ID: <f892d87df4a1bb83cefdde1a244f2b63@sonic.net>

On 2015-04-02 19:42, Ben Finney wrote:
> Alex Kleider <akleider at sonic.net> writes:
> 
>> A listing of /usr/bin/python* on my Ubuntu 14.04 LTS machine yields
>> the following:
>> alex at t61p:~$ ls -l /usr/bin/python*
>> [?]
>> -rwxr-xr-x 1 root root 3802224 Apr 11  2014 /usr/bin/python3.4m
>> lrwxrwxrwx 1 root root      10 Aug 23  2014 /usr/bin/python3m ->
>> python3.4m
>> 
>> What is python3.4m?
> 
> I can't tell you what it is. I can, though, tell you how to query what
> package installed it::
> 
>     $ dpkg --search /usr/bin/python3.4m
> 
> which might give some useful information.

It does indeed:
alex at t61p:~$  dpkg --search /usr/bin/python3.4m
python3.4-minimal: /usr/bin/python3.4m

This elaborates a bit:
https://launchpad.net/ubuntu/trusty/+package/python3.4-minimal

Thanks for the tip.

ak

From rajbirs799 at gmail.com  Fri Apr  3 05:58:28 2015
From: rajbirs799 at gmail.com (Rajbir Singh)
Date: Fri, 3 Apr 2015 09:28:28 +0530
Subject: [Tutor] Command Line Editting: How to improve options?
In-Reply-To: <1595076443.4131028.1428015746150.JavaMail.yahoo@mail.yahoo.com>
References: <20150402120751.GX25453@ando.pearwood.info>
 <1595076443.4131028.1428015746150.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <CAMTfo=SfPfUs=n8PwhDE5RCgTgC+6LXzRRBs5OzNM78UkFNCVA@mail.gmail.com>

pycharm is IDE for python, ive been using it for a while now, compiles
python script, works as a text editor, allows downloading third party libs,
so far i havnt found anything that i need as python coder and it doesnt
have!! give it a try -- "PyCharm"

On Fri, Apr 3, 2015 at 4:32 AM, J L <jnl_public at yahoo.com.dmarc.invalid>
wrote:

> Thank you Steve.
>
>
> This electronic mail including any attachments may contain information
> that is privileged, confidential, and/or otherwise protected from
> disclosure to anyone other than its intended recipient(s). Any
> dissemination of this electronic email or its contents including any
> attachments is prohibited without prior consent.
>
>
>
>      On Thursday, April 2, 2015 5:09 AM, Steven D'Aprano <
> steve at pearwood.info> wrote:
>
>
>  On Thu, Apr 02, 2015 at 06:36:03AM +0000, J L wrote:
> >  Win 7Python v 3.4.3
> > I'm new to Python and only have coursework under my belt in another
> > object oriented programming language as well as limited systems
> > skills. After launching Python from the command line with py.exe, it
> > appears that the interrupter starts up fine. I've read on Python.Org's
> > site in a tutorial section that some interrupters offer command line
> > editing beyond simple use of the arrow keys and backspace. It does not
> > appear that my environment is allowing these greater abilities. How
> > does one afford increased abilities to edit commands within Python's
> > interrupter? Thank you.
>
>
> Sadly, Windows does not offer much in the way of powerful interactive
> commands like most Linux shells do. You can try these options:
>
> - try using Python's IDLE:
>
> http://www.google.com.au/search?q=how+to+run+IDLE+python
>
> - Use a commercial third-party IDE ("Integrated Development
> Environment") such as PyCharm, Anaconda or Komodo. Some of them may cost
> money, but they may have free or trial versions.
>
> - Or a third-party editor such as Spyder, if it comes with its own
> interactive shell.
>
> - I can strongly recomment iPython, which is very powerful and includes
> a lot of command-line features that even Linux shells don't:
>
> http://ipython.org/
> ?
> If you've used Mathematica, you may love iPython's "notepad" feature.
>
> Now we start getting to slightly more complex options, which may not
> work, but it would be interesting to try:
>
> - Try installing pyreadline, and see it is will work with Python 3.4. If
> it does, you might be able to convince Python 3.4's rlcompleter module
> to work with it.
>
> - Still if pyreadline works with Python 3.4, you might like my command
> line tab completer and history module rather than the built-in one:
>
> http://code.google.com/p/tabhistory/source/browse/tabhistory.py
>
> I've never tested it on Windows, so I don't know if it will actually
> work or not.
>
>
> Good luck!
>
>
>
> --
> Steve
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From joe.farro at gmail.com  Sat Apr  4 11:42:39 2015
From: joe.farro at gmail.com (Joe Farro)
Date: Sat, 4 Apr 2015 09:42:39 +0000 (UTC)
Subject: [Tutor] Request review: A DSL for scraping a web page
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
 <mfja1a$p89$1@ger.gmane.org> <loom.20150402T153703-587@post.gmane.org>
Message-ID: <loom.20150404T105249-643@post.gmane.org>

Joe Farro <joe.farro <at> gmail.com> writes:

> 
> Thanks, Peter.
> 
> Peter Otten <__peter__ <at> web.de> writes:
> 
> > Can you give a real-world example where your DSL is significantly cleaner 
> > than the corresponding code using bs4, or lxml.xpath, or lxml.objectify?

Peter, I worked up what I hope is a fairly representative example. It scrapes
metadata from the 10 newest web-scraping questions on stackoverflow.
It's done with bs4 and take.

https://github.com/tiffon/take-examples/tree/master/samples/stackoverflow

I've posted on the bs4 discussion group asking for feedback on the bs4
version to make sure it's up to snuff. (The post is in new-member
purgatory, at the moment.)

In my opinion, the fact that take lacks an ability to define sub-routines is
a brutal deficiency. (As compared to defining functions like
`get_poster_details()` and `get_comment_activity()` in the bs4 version.)

On the bright side, I do like that the indentation of the take templates
semi-reflect the structure of the HTML document. However, the
indentation doesn't (always) reflect the hierarchy of the data being 
generated, which seems more clear.

Feedback is definitely welcome.

Thanks again!


From joe.farro at gmail.com  Sat Apr  4 18:24:10 2015
From: joe.farro at gmail.com (Joe Farro)
Date: Sat, 4 Apr 2015 16:24:10 +0000 (UTC)
Subject: [Tutor] Request review: A DSL for scraping a web page
References: <CAPA-Aq=yvg8R1L6-9A9ODFnydr3BpJ7_Ea--YNdndKHHs9YQYQ@mail.gmail.com>
 <mfja1a$p89$1@ger.gmane.org> <loom.20150402T153703-587@post.gmane.org>
 <loom.20150404T105249-643@post.gmane.org>
Message-ID: <loom.20150404T181909-435@post.gmane.org>

Joe Farro <joe.farro <at> gmail.com> writes:
> indentation doesn't (always) reflect the hierarchy of the data being 
> generated, which seems more clear.

Meant to say: 

However, the indentation doesn't (always) reflect the hierarchy of
the data being generated, which seems more clear **in the bs4
version**.


From robertvstepp at gmail.com  Sat Apr  4 18:49:08 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 4 Apr 2015 11:49:08 -0500
Subject: [Tutor] Use of "or" in a lambda expression
Message-ID: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>

Windows 7, Python 3.4.3

This code snippet is "Example 7-13" on page 383 from "Programming
Python, 4th ed." by Mark Lutz :

import sys
from tkinter import *

widget = Button(None,
            text='Hello event world!',
            command=(lambda: print('Hello lambda world!') or sys.exit()))
widget.pack()
widget.mainloop()

My question is about the lambda expression. The author states "...this
version uses an or operator to force two expressions to be run..."  I
am not understanding how 'or' causes this to happen. I guess I am
expecting the 'or' to result only in the print running without
executing sys.exit(). But that is not what happens--of course. I tried
substituting 'and' for 'or', but this results in only the print being
run! Obviously I have a significant misunderstanding of what is going
on.

Thanks!

-- 
boB

From steve at pearwood.info  Sat Apr  4 19:34:11 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 5 Apr 2015 03:34:11 +1000
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
Message-ID: <20150404173408.GJ25453@ando.pearwood.info>

On Sat, Apr 04, 2015 at 11:49:08AM -0500, boB Stepp wrote:
> Windows 7, Python 3.4.3
> 
> This code snippet is "Example 7-13" on page 383 from "Programming
> Python, 4th ed." by Mark Lutz :
> 
> import sys
> from tkinter import *
> 
> widget = Button(None,
>             text='Hello event world!',
>             command=(lambda: print('Hello lambda world!') or sys.exit()))

o_O

That's either the most horrible misuse of lambda I've ever seen, or a 
really cool and rather nifty trick. I'm not sure which :-)


> widget.pack()
> widget.mainloop()
> 
> My question is about the lambda expression. The author states "...this
> version uses an or operator to force two expressions to be run..."  I
> am not understanding how 'or' causes this to happen. I guess I am
> expecting the 'or' to result only in the print running without
> executing sys.exit(). But that is not what happens--of course. I tried
> substituting 'and' for 'or', but this results in only the print being
> run! Obviously I have a significant misunderstanding of what is going
> on.


Both `or` and `and` are "short-circuit" operators. Here is a truth-table 
for `a or b`:

           |a = True   False
-----------+-----------------
b = True   |    True   True
    False  |    True   False


If `a` is true, then `a or b` is true, regardless of whether b is true 
or false. So we can say that if `a` is true, `a or b` returns `a`.

If `a` is false, then `a or b` returns true if, and only if, `b` is 
true; otherwise it returns false. So we can say that if `a` is false, 
then `a or b` returns `b`.

So we can define our own "or" function like this:

def or_ (a, b):
    if a: return a
    else: return b

Unlike this function version, the `or` operator doesn't evaluate the `b` 
expression unless needed. So this piece of code:

    print(msg) or sys.exit()

runs like this:

(1) Evaluate the expression on the left of the operator: print(msg).
(2) That has the side-effect of printing the message, and returns
    the value None.
(3) Is None a true value? If so, `or` can short-circuit, and return
    it as its result.
(4) But None is a false value, so evaluate the expression on the
    right of the operator: sys.exit()
(5) Which has the side-effect of exiting the interpreter.
(6) The `or` operator would now return the result of sys.exit(), 
    if it had one; but it doesn't, since the interpreter has just 
    exited.


A cleaner example might be this:


py> def true():
...     print("calling true")
...     return 23  # a true-ish value
...
py> def false():
...     print("calling false")
...     return 0  # a false-ish value
...
py> true() or false()  # only the left operand is evaluated
calling true
23
py> true() or true()
calling true
23
py> false() or true()  # both operands are evaluated
calling false
calling true
23
py> false() or false()
calling false
calling false
0


The `and` operator is similar, except the truth-table looks like this:


           |a = True   False
-----------+-----------------
b = True   |    True   False
    False  |    False  False


Again, the right-hand operand is only evaluated if it is needed. This 
lets us write code like this:

    if mylist and mylist[0] == spam: eggs()


If mylist is empty, then `mylist and ...` doesn't even need to evaluate 
the right-hand operand, mylist[0] doesn't run and so does not fail. Only 
if mylist is a truthy value does mylist[0] run.


-- 
Steve

From robertvstepp at gmail.com  Sat Apr  4 20:06:59 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 4 Apr 2015 13:06:59 -0500
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <20150404173408.GJ25453@ando.pearwood.info>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
 <20150404173408.GJ25453@ando.pearwood.info>
Message-ID: <CANDiX9JDFUOf09UESwqiSirAHFrkWCMrzcA6gDGBHdg2Nc-FiA@mail.gmail.com>

On Sat, Apr 4, 2015 at 12:34 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Sat, Apr 04, 2015 at 11:49:08AM -0500, boB Stepp wrote:
>> Windows 7, Python 3.4.3
>>
>> This code snippet is "Example 7-13" on page 383 from "Programming
>> Python, 4th ed." by Mark Lutz :
>>
>> import sys
>> from tkinter import *
>>
>> widget = Button(None,
>>             text='Hello event world!',
>>             command=(lambda: print('Hello lambda world!') or sys.exit()))
>
> o_O
>
> That's either the most horrible misuse of lambda I've ever seen, or a
> really cool and rather nifty trick. I'm not sure which :-)

Now that I have read (and hopefully understand) your entire response,
I am wondering the same thing in the sense that my understanding of
Python's intent is for clearly readable code and this usage isn't
clear without some thought (At least for me!).

>> widget.pack()
>> widget.mainloop()
>>
>> My question is about the lambda expression. The author states "...this
>> version uses an or operator to force two expressions to be run..."  I
>> am not understanding how 'or' causes this to happen. I guess I am
>> expecting the 'or' to result only in the print running without
>> executing sys.exit(). But that is not what happens--of course. I tried
>> substituting 'and' for 'or', but this results in only the print being
>> run! Obviously I have a significant misunderstanding of what is going
>> on.
>
>
> Both `or` and `and` are "short-circuit" operators. Here is a truth-table

I get and understand the short-circuit logic. This isn't what got me!

[...]

> expression unless needed. So this piece of code:
>
>     print(msg) or sys.exit()
>
> runs like this:
>
> (1) Evaluate the expression on the left of the operator: print(msg).
> (2) That has the side-effect of printing the message, and returns
>     the value None.

This was my 'gotcha'. I forgot (but knew) that print functions return
None. Perhaps this constant switching back and forth between using
Python 2 at work and Python 3 at home is addling my brain? Also, even
if I had recalled the return of None, I might have missed that the
"side-effect" still occurs, i.e., the actual printing.

[...]

> The `and` operator is similar, except the truth-table looks like this:
>
>
>            |a = True   False
> -----------+-----------------
> b = True   |    True   False
>     False  |    False  False

And of course since print returns None, the short-circuit evaluation
causes the sys.exit() never to be seen.

Even though I snipped out most of your very well-constructed examples,
Steve, I have to say, you have a knack for making things abundantly
clear! You tutor very well, indeed, and I am appreciative!


-- 
boB

From robertvstepp at gmail.com  Sat Apr  4 21:21:19 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 4 Apr 2015 14:21:19 -0500
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <20150404173408.GJ25453@ando.pearwood.info>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
 <20150404173408.GJ25453@ando.pearwood.info>
Message-ID: <CANDiX9Jdc4O3oExpOw2n-N42kZctRA=daxp3HcyfV7eHGjH+Kw@mail.gmail.com>

On Sat, Apr 4, 2015 at 12:34 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Sat, Apr 04, 2015 at 11:49:08AM -0500, boB Stepp wrote:
>> Windows 7, Python 3.4.3
>>
>> This code snippet is "Example 7-13" on page 383 from "Programming
>> Python, 4th ed." by Mark Lutz :
>>
>> import sys
>> from tkinter import *
>>
>> widget = Button(None,
>>             text='Hello event world!',
>>             command=(lambda: print('Hello lambda world!') or sys.exit()))
>
> o_O
>
> That's either the most horrible misuse of lambda I've ever seen, or a
> really cool and rather nifty trick. I'm not sure which :-)

Re-reading the paragraph relevant to Mr. Lutz's example, perhaps I
should quote the full paragraph:

"This code is a bit tricky because lambdas can contain only an
expression; to emulate the original script, this version uses an or
operator to force two expressions to be run (print works as the first,
because it's a function call in Python 3.X--we don't need to resort to
using sys.stdout directly)."

I think the key thought of the author here is he showing how to
rewrite an earlier example that explicitly defines a quit() function,
which both prints and then exits the program,  to using a lambda
expression. I don't think his intent is to say that the lambda
expression is to be preferred (Or is he?).

To my mind, would:

def quit():
    print('Hello lambda world!')
    sys.exit()

and:

widget = Button(None, text='Hello event world!', command=quit)

be preferable Python style?

boB

From robertvstepp at gmail.com  Sat Apr  4 21:32:25 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 4 Apr 2015 14:32:25 -0500
Subject: [Tutor] Request review: A DSL for scraping a web page
In-Reply-To: <1428004185.39042.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
References: <1428004185.39042.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
Message-ID: <CANDiX9L6j=a8ARuW1QnPeFbP02tpYe+auvGWW46eAMyKqaAR9Q@mail.gmail.com>

On Thu, Apr 2, 2015 at 2:49 PM, Albert-Jan Roskam
<fomcl at yahoo.com.dmarc.invalid> wrote:
>
> -----------------------------
> On Thu, Apr 2, 2015 1:17 PM CEST Alan Gauld wrote:
>
>>On 02/04/15 12:09, Dave Angel wrote:
>>
>>> Ah, Jon Bentley (notice the extra 'e').  I should dig out my *Pearls
>>> books, and have a trip down memory lane.  I bet 95% of those are still
>>> useful, even if they refer to much earlier versions of language(s).
>>
>>Yes, the Pearls books should be required reading for all new programmers. The lessons are pretty timeless, it's only the
>>languages that change - and most of his examples seem to be
>>in a kind of pseudo Pascal dialect rather than real code anyway.
>>
>>I believe they've been re-released as a single volume now.
>
> Is this the book you are referring to?
> http://www.amazon.com/Programming-Pearls-2nd-Edition-Bentley/dp/0201657880

This thread inspired me to order both books from Amazon. The one
linked to above by Alan is an expanded and somewhat rewritten edition
of the original. It does NOT include "More Programming Pearls". I just
today received my copy of "Programming Pearls, 2nd ed."  To quote from
part of the author's preface of "Programming Pearls, 2nd ed.":

"To Readers of the First Edition

     I hope that your first response as you thumb through this edition
of the book is, 'This sure looks familiar.' A few minutes later, I
hope that you'll observe, 'I've never seen that before.'
     This version has the same focus as the first edition, but is set
in a larger context. Computing has grown substantially in important
areas such as databases, networking and user interfaces. Most
programmers should be familiar users of such technologies. At the
center of each of those areas, though, is a hard core of programming
problems. Those programs remain the theme of this book. This edition
of the book is a slightly larger fish in a much larger pond.
     ..."

HTH
-- 
boB

From danny.yoo at gmail.com  Sat Apr  4 22:10:05 2015
From: danny.yoo at gmail.com (Danny Yoo)
Date: Sat, 4 Apr 2015 13:10:05 -0700
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <CANDiX9Jdc4O3oExpOw2n-N42kZctRA=daxp3HcyfV7eHGjH+Kw@mail.gmail.com>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
 <20150404173408.GJ25453@ando.pearwood.info>
 <CANDiX9Jdc4O3oExpOw2n-N42kZctRA=daxp3HcyfV7eHGjH+Kw@mail.gmail.com>
Message-ID: <CAGZAPF5YGyArQSmrtpRYOWfi-jQ9iLGV2Yv4+5CN=J=_aRRf4w@mail.gmail.com>

>
> To my mind, would:
>
> def quit():
>     print('Hello lambda world!')
>     sys.exit()
>
> and:
>
> widget = Button(None, text='Hello event world!', command=quit)
>
> be preferable Python style?
>

Yes, I'd prefer this much more, compared to  the original.

From alan.gauld at btinternet.com  Sat Apr  4 22:35:26 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 04 Apr 2015 21:35:26 +0100
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
Message-ID: <mfphud$mcn$1@ger.gmane.org>

On 04/04/15 17:49, boB Stepp wrote:

> widget = Button(None,
>              text='Hello event world!',
>              command=(lambda: print('Hello lambda world!') or sys.exit()))

> am not understanding how 'or' causes this to happen. I guess I am
> expecting the 'or' to result only in the print running without

This is explained in more detail in the functional programming
topic of my tutorial. It's called short circuit evaluation of
boolean expressions if you want to look it up on wikipedia
or elsewhere.

The short version is that to evaluate an OR Python looks at
the first expression and if its true it returns the result
  - since any single True expression makes the OR true too.

If the first expression is false-like (eg None returned from
a print() ) then it must evaluate the second expression to
be sure of the overall OR result.

So by putting a print() which returns None, first Lutz
ensures the second expression is also evaluated.

He could have done it in various other ways too:

eg.
lambda : all(print('Hello lambda world!'), sys.exit() )

But the OR style is established as a kind of idiom,
not just in Python but several other languages too.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From robertvstepp at gmail.com  Sat Apr  4 23:57:05 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 4 Apr 2015 16:57:05 -0500
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <mfphud$mcn$1@ger.gmane.org>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
 <mfphud$mcn$1@ger.gmane.org>
Message-ID: <CANDiX9KPkprGHH_g7ekmQa3XAus1wy_OzQmxn=S5VBZs_CAYHw@mail.gmail.com>

On Sat, Apr 4, 2015 at 3:35 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> He could have done it in various other ways too:
>
> eg.
> lambda : all(print('Hello lambda world!'), sys.exit() )

Is this what you meant? Because print will always return False. Or did
you actually mean:

lambda: any(print('Hello lambda world!'), sys.exit())

> But the OR style is established as a kind of idiom,
> not just in Python but several other languages too.

So this is not unusual for Python. BTW, what are some of the other
languages where this type of expression might be commonly used?


-- 
boB

From davea at davea.name  Sun Apr  5 00:40:42 2015
From: davea at davea.name (Dave Angel)
Date: Sat, 04 Apr 2015 18:40:42 -0400
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <CANDiX9KPkprGHH_g7ekmQa3XAus1wy_OzQmxn=S5VBZs_CAYHw@mail.gmail.com>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
 <mfphud$mcn$1@ger.gmane.org>
 <CANDiX9KPkprGHH_g7ekmQa3XAus1wy_OzQmxn=S5VBZs_CAYHw@mail.gmail.com>
Message-ID: <5520686A.1010106@davea.name>

On 04/04/2015 05:57 PM, boB Stepp wrote:
> On Sat, Apr 4, 2015 at 3:35 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>> He could have done it in various other ways too:
>>
>> eg.
>> lambda : all(print('Hello lambda world!'), sys.exit() )
>
> Is this what you meant? Because print will always return False. Or did
> you actually mean:
>
> lambda: any(print('Hello lambda world!'), sys.exit())
>
>> But the OR style is established as a kind of idiom,
>> not just in Python but several other languages too.
>
> So this is not unusual for Python. BTW, what are some of the other
> languages where this type of expression might be commonly used?
>
>

I don't think I've ever seen it used in Python.  But it's quite common 
in Perl scripts and bash scripts that I've seen.  In the case of bash, 
one might do something like:

      prog1   &&   prog2

and prog2 gets executed only if prog1 had a successful completion

-- 
DaveA

From breamoreboy at yahoo.co.uk  Sun Apr  5 01:30:10 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 05 Apr 2015 00:30:10 +0100
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
Message-ID: <mfps65$h9p$1@ger.gmane.org>

On 04/04/2015 17:49, boB Stepp wrote:
> Windows 7, Python 3.4.3
>
> This code snippet is "Example 7-13" on page 383 from "Programming
> Python, 4th ed." by Mark Lutz :
>
> import sys
> from tkinter import *
>
> widget = Button(None,
>              text='Hello event world!',
>              command=(lambda: print('Hello lambda world!') or sys.exit()))
> widget.pack()
> widget.mainloop()
>
> My question is about the lambda expression. The author states "...this
> version uses an or operator to force two expressions to be run..."  I
> am not understanding how 'or' causes this to happen. I guess I am
> expecting the 'or' to result only in the print running without
> executing sys.exit(). But that is not what happens--of course. I tried
> substituting 'and' for 'or', but this results in only the print being
> run! Obviously I have a significant misunderstanding of what is going
> on.
>
> Thanks!
>

The print function in Python 3 always returns None, which is a false 
value.  As we're talking 'or' here the second part wills always get run, 
hence in this case sys.exit() gets called.

I'd try the same thing by using your own function.

def myprint(mystr):
     print(mystr)
     return 0

Substitute print in the lambda with myprint and try it, then replace the 
'0' with a '1' and see what happens.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From alan.gauld at btinternet.com  Sun Apr  5 01:55:16 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 05 Apr 2015 00:55:16 +0100
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <CANDiX9KPkprGHH_g7ekmQa3XAus1wy_OzQmxn=S5VBZs_CAYHw@mail.gmail.com>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
 <mfphud$mcn$1@ger.gmane.org>
 <CANDiX9KPkprGHH_g7ekmQa3XAus1wy_OzQmxn=S5VBZs_CAYHw@mail.gmail.com>
Message-ID: <mfptl4$6me$1@ger.gmane.org>

On 04/04/15 22:57, boB Stepp wrote:
> On Sat, Apr 4, 2015 at 3:35 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>> He could have done it in various other ways too:
>>
>> eg.
>> lambda : all(print('Hello lambda world!'), sys.exit() )
>
> Is this what you meant? Because print will always return False. Or did
> you actually mean:
>
> lambda: any(print('Hello lambda world!'), sys.exit())

any() would be more obvious, but in my interpreter
both any() and all() evaluate both functions before
testing the results. At least they do once you
fix the TypeError : they should be in a list/tuple...

lambda : all([print('Hello lambda world!'), sys.exit()] )

> So this is not unusual for Python. BTW, what are some of the other
> languages where this type of expression might be commonly used?

It's sometimes used in Turbo Pascal/Delphi and also in Perl  (a lot!).
I think I've seen it used in PHP too.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From wolfrage8765 at gmail.com  Sun Apr  5 03:53:28 2015
From: wolfrage8765 at gmail.com (WolfRage)
Date: Sat, 04 Apr 2015 21:53:28 -0400
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <20150403032331.GB25453@ando.pearwood.info>
References: <551D6BD4.8030507@gmail.com>
 <20150402180712.GY25453@ando.pearwood.info> <551D9A31.3040509@gmail.com>
 <20150403032331.GB25453@ando.pearwood.info>
Message-ID: <55209598.7010801@gmail.com>

<SNIP>
So I was surprised I did not get more feedback on my abused coroutine, 
maybe that is good or bad, not sure.
Any ways I am on to trying to make that coroutine act more like the 
State Pattern from Gang of Four. And well reading this:
http://gameprogrammingpatterns.com/state.html
I am not sure how to do this:
class Heroine
{
public:
   virtual void handleInput(Input input)
   {
     state_->handleInput(*this, input);
   }

   virtual void update()
   {
     state_->update(*this);
   }

   // Other methods...
private:
   HeroineState* state_;
};

(Pointing to the different classes. Since C++ has virtual methods but 
Python does not?) in Python? Do I just reference the new method? Because 
state_ will always be the correct object?

From steve at pearwood.info  Sun Apr  5 05:11:33 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 5 Apr 2015 13:11:33 +1000
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <CANDiX9Jdc4O3oExpOw2n-N42kZctRA=daxp3HcyfV7eHGjH+Kw@mail.gmail.com>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
 <20150404173408.GJ25453@ando.pearwood.info>
 <CANDiX9Jdc4O3oExpOw2n-N42kZctRA=daxp3HcyfV7eHGjH+Kw@mail.gmail.com>
Message-ID: <20150405031132.GL25453@ando.pearwood.info>

On Sat, Apr 04, 2015 at 02:21:19PM -0500, boB Stepp wrote:

> To my mind, would:
> 
> def quit():
>     print('Hello lambda world!')
>     sys.exit()
> 
> and:
> 
> widget = Button(None, text='Hello event world!', command=quit)
> 
> be preferable Python style?

Hell yes!


Using `or` to run functions purely for their side-effects (in this case, 
printing and exiting) makes a nice trick, but I wouldn't use for real.

On the other hand, using `or` for its value is perfectly acceptable. 
E.g. one common idiom might be to iterate over something which might be 
None:

for value in maybe_list or []:
    ...


If `maybe_list` is a non-empty list, it is used; if it is an empty list, 
the second operand (also an empty list) is used, but that's okay since 
they are both empty lists; and if it is None, then the second operand is 
used instead. This is a reasonable idiom to use, and prior to Python 2.5 
it was the closest thing the language had to a "ternary if operator".

These days, the `or` idiom is less common except in old code or code 
that has to run on Python 2.4 or older. Instead, we might write:

for value in (maybe_list if maybe_list is not None else []):
    ...

I'm not entirely sure that's an improvement :-)

-- 
Steve

From cs at zip.com.au  Sun Apr  5 05:21:23 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Sun, 5 Apr 2015 13:21:23 +1000
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <20150404173408.GJ25453@ando.pearwood.info>
References: <20150404173408.GJ25453@ando.pearwood.info>
Message-ID: <20150405032123.GA47234@cskk.homeip.net>

On 05Apr2015 03:34, Steven D'Aprano <steve at pearwood.info> wrote:
>On Sat, Apr 04, 2015 at 11:49:08AM -0500, boB Stepp wrote:
>> widget = Button(None,
>>             text='Hello event world!',
>>             command=(lambda: print('Hello lambda world!') or sys.exit()))
>
>That's either the most horrible misuse of lambda I've ever seen, or a
>really cool and rather nifty trick. I'm not sure which :-)

I think it is misuse. When I need to run two functions like that I tend to use 
a tuple:

  lambda: (f1(), f2())

Since Python evaluates left to right, these functions are called f1 first, then 
f2.

Using "or" introduces a reliance on f1 returning a falsish value. Dodgy and 
unreliable. Not to mention conflating the supposed Boolean value computed by 
the expression with the program's purpose.

Like others, I agree it is generally better to define a function more normally 
and just name in instead of inlining a lambda. But sometimes (rarely) that 
makes for harder to read code structure (though easier to read function 
internals).

Anyway, faced with a desire to use a lambda here, I would choose a tuple.

Cheers,
Cameron Simpson <cs at zip.com.au>

This is my simple religion. There is no need for temples; no need for
complicated philosophy. Our own brain, our own heart is our temple; the
philosophy is kindness.	- Dalai Lama

From steve at pearwood.info  Sun Apr  5 05:32:08 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 5 Apr 2015 13:32:08 +1000
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <mfptl4$6me$1@ger.gmane.org>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
 <mfphud$mcn$1@ger.gmane.org>
 <CANDiX9KPkprGHH_g7ekmQa3XAus1wy_OzQmxn=S5VBZs_CAYHw@mail.gmail.com>
 <mfptl4$6me$1@ger.gmane.org>
Message-ID: <20150405033208.GM25453@ando.pearwood.info>

On Sun, Apr 05, 2015 at 12:55:16AM +0100, Alan Gauld wrote:
> On 04/04/15 22:57, boB Stepp wrote:
> >On Sat, Apr 4, 2015 at 3:35 PM, Alan Gauld <alan.gauld at btinternet.com> 
> >wrote:
> >>He could have done it in various other ways too:
> >>
> >>eg.
> >>lambda : all(print('Hello lambda world!'), sys.exit() )
> >
> >Is this what you meant? Because print will always return False. Or did
> >you actually mean:
> >
> >lambda: any(print('Hello lambda world!'), sys.exit())
> 
> any() would be more obvious, but in my interpreter
> both any() and all() evaluate both functions before
> testing the results. At least they do once you
> fix the TypeError : they should be in a list/tuple...
> 
> lambda : all([print('Hello lambda world!'), sys.exit()] )


That's because the sys.exit() call leaves the interpreter because any() 
gets a chance to raise TypeError :-) Your code:

lambda: all(print('Hello lambda world!'), sys.exit())

is equivalent to this:

a = print('Hello lambda world!')
b = sys.exit()  # Goodbye cruel world!
all(a, b)  # this never gets called


so you could replace the call to all() with any(), or len(), or 
zxcvbnm() if you like, it makes no difference at all.

The moral equivalent of the original `or` trick would be something like 
this:

any(spam() for spam in [lambda: print("Hello lambda world!"), os.exit])

which now avoids calling os.exit until necessary. E.g. we might write a 
function which prints a message, then has a 50% chance of exiting:


any(spam() for spam in [lambda: print("Hello lambda world!"), 
                        lambda: random.random() > 0.5,
                        lambda: print("Goodbye cruel world!"),
                        os.exit]
                        )

will always print Hello, and fifty percent of the time will print 
Goodbye then exit, otherwise it will return True.


-- 
Steve

From steve at pearwood.info  Sun Apr  5 06:08:44 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 5 Apr 2015 14:08:44 +1000
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <551D6BD4.8030507@gmail.com>
References: <551D6BD4.8030507@gmail.com>
Message-ID: <20150405040844.GO25453@ando.pearwood.info>

On Thu, Apr 02, 2015 at 12:18:28PM -0400, WolfRage wrote:
> These are just some questions that I have regarding the topic of 
> Functional Programming. I am working towards a more functional approach 
> to programming but acknowledge that it is far from Functional, 
> especially since this is mostly impossible in Python.

You might like to read this:

https://codewords.recurse.com/issues/one/an-introduction-to-functional-programming

I'm not sure whether I agree with the author, but it's worth reading.


-- 
Steve

From robertvstepp at gmail.com  Sun Apr  5 05:45:27 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 4 Apr 2015 22:45:27 -0500
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <mfptl4$6me$1@ger.gmane.org>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
 <mfphud$mcn$1@ger.gmane.org>
 <CANDiX9KPkprGHH_g7ekmQa3XAus1wy_OzQmxn=S5VBZs_CAYHw@mail.gmail.com>
 <mfptl4$6me$1@ger.gmane.org>
Message-ID: <CANDiX9JO3+ko=dxO5WWqNMKg1SrDrfFK640fZWpNC8YmYPy2vQ@mail.gmail.com>

On Sat, Apr 4, 2015 at 6:55 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 04/04/15 22:57, boB Stepp wrote:
>>
>> On Sat, Apr 4, 2015 at 3:35 PM, Alan Gauld <alan.gauld at btinternet.com>
>> wrote:
>>>
>>> He could have done it in various other ways too:
>>>
>>> eg.
>>> lambda : all(print('Hello lambda world!'), sys.exit() )
>>
>>
>> Is this what you meant? Because print will always return False. Or did
>> you actually mean:
>>
>> lambda: any(print('Hello lambda world!'), sys.exit())
>
>
> any() would be more obvious, but in my interpreter
> both any() and all() evaluate both functions before
> testing the results. At least they do once you
> fix the TypeError : they should be in a list/tuple...
>
> lambda : all([print('Hello lambda world!'), sys.exit()] )

Well, now I am curious as to why the "all" form evaluates BOTH
elements. Apparently it does not apply the short-circuit logic we have
been discussing, or it would stop evaluating after the print statement
return.  Why is that?

-- 
boB

From cs at zip.com.au  Sun Apr  5 06:22:30 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Sun, 5 Apr 2015 14:22:30 +1000
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <CANDiX9JO3+ko=dxO5WWqNMKg1SrDrfFK640fZWpNC8YmYPy2vQ@mail.gmail.com>
References: <CANDiX9JO3+ko=dxO5WWqNMKg1SrDrfFK640fZWpNC8YmYPy2vQ@mail.gmail.com>
Message-ID: <20150405042230.GA16357@cskk.homeip.net>

On 04Apr2015 22:45, boB Stepp <robertvstepp at gmail.com> wrote:
>On Sat, Apr 4, 2015 at 6:55 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>> lambda : all([print('Hello lambda world!'), sys.exit()] )
>
>Well, now I am curious as to why the "all" form evaluates BOTH
>elements. Apparently it does not apply the short-circuit logic we have
>been discussing, or it would stop evaluating after the print statement
>return.  Why is that?

Because the list/tuple is constructed entirely before all() is called. All() 
operates only on the final values.

Cheers,
Cameron Simpson <cs at zip.com.au>

Yesterday, I was running a CNC plasma cutter that's controlled by Windows XP.
This is a machine that moves around a plasma torch that cuts thick steel
plate. ?A "New Java update is available" window popped up while I was
working. ?Not good. - John Nagle

From davea at davea.name  Sun Apr  5 07:16:32 2015
From: davea at davea.name (Dave Angel)
Date: Sun, 05 Apr 2015 01:16:32 -0400
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <55209598.7010801@gmail.com>
References: <551D6BD4.8030507@gmail.com>
 <20150402180712.GY25453@ando.pearwood.info> <551D9A31.3040509@gmail.com>
 <20150403032331.GB25453@ando.pearwood.info> <55209598.7010801@gmail.com>
Message-ID: <5520C530.1010902@davea.name>

On 04/04/2015 09:53 PM, WolfRage wrote:
> <SNIP>

>
> (Pointing to the different classes. Since C++ has virtual methods but
> Python does not?)

I'd say that all methods in Python are virtual, except for those which 
are classmethod or staticmethod.


-- 
DaveA

From steve at pearwood.info  Sun Apr  5 07:23:47 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 5 Apr 2015 15:23:47 +1000
Subject: [Tutor] Functional Programming in Python
In-Reply-To: <55209598.7010801@gmail.com>
References: <551D6BD4.8030507@gmail.com>
 <20150402180712.GY25453@ando.pearwood.info> <551D9A31.3040509@gmail.com>
 <20150403032331.GB25453@ando.pearwood.info> <55209598.7010801@gmail.com>
Message-ID: <20150405052346.GP25453@ando.pearwood.info>

On Sat, Apr 04, 2015 at 09:53:28PM -0400, WolfRage wrote:
> <SNIP>
> So I was surprised I did not get more feedback on my abused coroutine, 
> maybe that is good or bad, not sure.

Perhaps people didn't understand it. Or see it :-)

> Any ways I am on to trying to make that coroutine act more like the 
> State Pattern from Gang of Four. And well reading this:
> http://gameprogrammingpatterns.com/state.html

Now you're fighting the paradigm. Functional programming works best for 
code that avoids side-effects. But changes of state are naturally a 
side-effect! I was sitting, now I am walking. It's still me, but my 
state is different.

Now of course you can emulate state changes using purely functional 
code, but its harder and less efficient.


> I am not sure how to do this:
> class Heroine
> {
> public:
>   virtual void handleInput(Input input)
>   {
>     state_->handleInput(*this, input);
>   }
> 
>   virtual void update()
>   {
>     state_->update(*this);
>   }
> 
>   // Other methods...
> private:
>   HeroineState* state_;
> };
> 
> (Pointing to the different classes. Since C++ has virtual methods but 
> Python does not?) in Python? Do I just reference the new method? Because 
> state_ will always be the correct object?

Hmmm, I'm not sure, but I think that we would say that *all* Python 
methods are virtual in C++ terms. They are all resolved at runtime.

There are a few ways we might do this in Python.

class Heroine:
    def __init__(self):
        self.state = "standing"  # Or use an Enum in Python 3.4

    def jump(self):
        if self.state == "standing":
            self.state = "jumping"
            ...
        elif self.state == "jumping":
            pass

    # Dispatch table of keys to actions.
    KEYMAP = {'b': jump,
              'd': duck,
              'f': run,
              ...
             }

    def handle_keypress(self, key):
        method = self.KEYMAP.get(key, None)
        if method:
            method(self)


We look up the key press, and get a reference to the method itself, not 
the name of the method. (Or None.) We then call that method by providing 
self as the first argument. Nice and easy. It's so easy that I'm not 
sure if it's even worth discussing alternatives.

Another alternative might be to use delegation, or object composition. 
Give the Heroine class all the methods which don't change. For the 
methods which do change, create a separate FooState class for each 
state:

class JumpingState:
    def jump(self):
        pass

    def duck(self):
        ...

class RunningState: 
    ...


class Heroine:
    def __init__(self):
        self.state = StandingState()

    # Dispatch table of keys to method names.
    KEYMAP = {'b': 'jump',
              'd': 'duck',
              'f': 'run',
              ...
             }

    def handle_keypress(self, key):
        name = self.KEYMAP.get(key, None)
        if name:
            newstate = getattr(self.state, name)()
            if newstate:
                self.state = newstate()


Methods of the state object can signal a change of state by returning 
the class representing the new state. Otherwise, they can return None to 
signal no change of state.

Here is how we might do this using inheritence instead of composition. 
Start with a base class and a bunch of default methods which 
conditionally raise:


class BaseHeroine:

    def jump(self):
        if self.__class__ is BaseHeroine:
            raise RuntimeError

    def run(self):
        if self.__class__ is BaseHeroine:
            raise RuntimeError

    def duck(self):
        if self.__class__ is BaseHeroine:
            raise RuntimeError

    # Dispatch table of keys to method names.
    KEYMAP = {'b': 'jump',
              'd': 'duck',
              'f': 'run',
              ...
             }

    def handle_keypress(self, key):
        name = self.KEYMAP.get(key, None)
        if name:
            getattr(self.state, name)()


Now have a bunch of subclasses, one for each state. Override only the 
methods you need. (Remember, the default behaviour for each method is to 
do nothing, if called from a subclass. They only raise if called from 
the base class.)

class JumpHeroine(BaseHeroine):  ...

class StandHeroine(BaseHeroine):  ...

class RunHeroine(BaseHeroine): ...



Now create an instance, and set its state:

heroine = BaseHeroine()
heroine.__class__ = StandHeroine


State transitions are managed by *changing the instance's class*. 
Methods can do that themselves:

    def spam(self):
        self.__class__ = RunHeroine  # Don't instantiate the class.
        print("Spam spam spam loverlllly spam!!!!")




Now, I haven't tested any of the above code, but here is a short and 
simple demonstration showing that it does work:


py> class X:
...     def display(self):
...             print("in X")
...     def method(self):
...             self.display()
...             print(self, type(self), self.__class__)
...
py> class Y(X):
...     def display(self):
...             print("in Y")
...
py> instance = X()
py> instance.method()
in X
<__main__.X object at 0xb7a9d84c> <class '__main__.X'> <class '__main__.X'>
py> instance.__class__ = Y  # dynamically change the class
py> instance.method()
in Y
<__main__.Y object at 0xb7a9d84c> <class '__main__.Y'> <class '__main__.Y'>


Cool, huh? :-)

Having written all this out, I'm now starting to lean towards the 
inheritence version.

Now, how you would this in a purely functional style... I have no idea!


-- 
Steve

From alan.gauld at btinternet.com  Sun Apr  5 10:06:21 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 05 Apr 2015 09:06:21 +0100
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <CANDiX9JO3+ko=dxO5WWqNMKg1SrDrfFK640fZWpNC8YmYPy2vQ@mail.gmail.com>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
 <mfphud$mcn$1@ger.gmane.org>
 <CANDiX9KPkprGHH_g7ekmQa3XAus1wy_OzQmxn=S5VBZs_CAYHw@mail.gmail.com>
 <mfptl4$6me$1@ger.gmane.org>
 <CANDiX9JO3+ko=dxO5WWqNMKg1SrDrfFK640fZWpNC8YmYPy2vQ@mail.gmail.com>
Message-ID: <mfqqdt$9c3$1@ger.gmane.org>

On 05/04/15 04:45, boB Stepp wrote:

>>>> He could have done it in various other ways too:
>>>>
>>>> eg.
>>>> lambda : all(print('Hello lambda world!'), sys.exit() )

> Well, now I am curious as to why the "all" form evaluates BOTH
> elements. Apparently it does not apply the short-circuit logic we have
> been discussing, or it would stop evaluating after the print statement
> return.  Why is that?

Because I didn't really think the example through properly.
I just grabbed the first thing I could think of that would
evaluate both functions... As Cameron has shown, a much more
elegant solution is just to use a tuple as the body of
the lambda.

That's effectively what's happening indside the all()/any()
calls.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From marcus.luetolf at bluewin.ch  Sun Apr  5 13:11:06 2015
From: marcus.luetolf at bluewin.ch (=?iso-8859-1?Q?Marcus_L=FCtolf?=)
Date: Sun, 5 Apr 2015 13:11:06 +0200
Subject: [Tutor] Loops
Message-ID: <40c601d06f91$398b5cc0$aca21640$@bluewin.ch>

Why do I get this traceback with the infinite loop below but not with the
definitw loop (bottom of mail)?
Thanks for help, Marcus.

 

count = 0

total = 0

while True:

    x = raw_input('Enter a number')

    count = count + 1

    total = total + x

    print count, total, (total/count)

 

 

Traceback (most recent call last):

  File "C:\Python27\enter_a_number.py", line 6, in <module>

    total = total + x

TypeError: unsupported operand type(s) for +: 'int' and 'str'



---
Diese E-Mail wurde von Avast Antivirus-Software auf Viren gepr?ft.
http://www.avast.com

From breamoreboy at yahoo.co.uk  Sun Apr  5 15:11:36 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 05 Apr 2015 14:11:36 +0100
Subject: [Tutor] Loops
In-Reply-To: <40c601d06f91$398b5cc0$aca21640$@bluewin.ch>
References: <40c601d06f91$398b5cc0$aca21640$@bluewin.ch>
Message-ID: <mfrcab$f20$1@ger.gmane.org>

On 05/04/2015 12:11, Marcus L?tolf wrote:
> Why do I get this traceback with the infinite loop below but not with the
> definitw loop (bottom of mail)?
> Thanks for help, Marcus.
>
> count = 0
> total = 0
> while True:
>
>      x = raw_input('Enter a number')
>      count = count + 1
>      total = total + x
>      print count, total, (total/count)
>
> Traceback (most recent call last):
>
>    File "C:\Python27\enter_a_number.py", line 6, in <module>
>
>      total = total + x
>
> TypeError: unsupported operand type(s) for +: 'int' and 'str'
>

raw_input returns a string, you must convert that to an int (or some 
other numeric type) before you can add it to your total.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From alan.gauld at btinternet.com  Sun Apr  5 15:18:36 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 05 Apr 2015 14:18:36 +0100
Subject: [Tutor] Loops
In-Reply-To: <40c601d06f91$398b5cc0$aca21640$@bluewin.ch>
References: <40c601d06f91$398b5cc0$aca21640$@bluewin.ch>
Message-ID: <mfrcnc$kri$1@ger.gmane.org>

On 05/04/15 12:11, Marcus L?tolf wrote:
> Why do I get this traceback with the infinite loop below but not with the
> definitw loop (bottom of mail)?

I don;t see anyt loops at the bottom.
But as for this one...

> count = 0
> total = 0
>
> while True:
>      x = raw_input('Enter a number')

raw_input reads a character string. You need to converrt it to a number:

       x = int(raw_input('Enter a number') )


>      count = count + 1
>      total = total + x

Without the conversion you are trying to add a string
to a number which is illegal in Python.

>      print count, total, (total/count)

> Traceback (most recent call last):
>    File "C:\Python27\enter_a_number.py", line 6, in <module>
>      total = total + x
> TypeError: unsupported operand type(s) for +: 'int' and 'str'

Which is what the error is telling you.


HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From steve at pearwood.info  Sun Apr  5 16:54:33 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 6 Apr 2015 00:54:33 +1000
Subject: [Tutor] Loops
In-Reply-To: <40c601d06f91$398b5cc0$aca21640$@bluewin.ch>
References: <40c601d06f91$398b5cc0$aca21640$@bluewin.ch>
Message-ID: <20150405145432.GR25453@ando.pearwood.info>

On Sun, Apr 05, 2015 at 01:11:06PM +0200, Marcus L?tolf wrote:
> Why do I get this traceback with the infinite loop below but not with the
> definitw loop (bottom of mail)?

You forgot to show the definite loop, but the error in the infinite loop 
is explained by the error message. You should read the error message 
carefully, it will often explain the problem you are having. Further 
comments below.

> count = 0
> total = 0
> while True:
>     x = raw_input('Enter a number')
>     count = count + 1
>     total = total + x
>     print count, total, (total/count)
>  
> 
> Traceback (most recent call last):
>   File "C:\Python27\enter_a_number.py", line 6, in <module>
>     total = total + x
> TypeError: unsupported operand type(s) for +: 'int' and 'str'

The traceback shows you the line causing the error:

    total = total + x

and describes the error: you cannot add an int and a str. Try it at the 
interactive interpreter:

py> 23 + "42"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'


The `total` variable starts as an int:

    total = 0

and x is a string. Just because you print "Enter a number" doesn't mean 
that Python magically turns x into a number. You are responsible for 
turning the string into a number. Try:

    x = int(raw_input('Enter a number'))



-- 
Steve

From robertvstepp at gmail.com  Sun Apr  5 21:29:32 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 5 Apr 2015 14:29:32 -0500
Subject: [Tutor] Use of "or" in a lambda expression
In-Reply-To: <mfqqdt$9c3$1@ger.gmane.org>
References: <CANDiX9+sSt3CwZ=0ET6UJZ=fCy-dumq=r8sVmRACF85E5fnhcA@mail.gmail.com>
 <mfphud$mcn$1@ger.gmane.org>
 <CANDiX9KPkprGHH_g7ekmQa3XAus1wy_OzQmxn=S5VBZs_CAYHw@mail.gmail.com>
 <mfptl4$6me$1@ger.gmane.org>
 <CANDiX9JO3+ko=dxO5WWqNMKg1SrDrfFK640fZWpNC8YmYPy2vQ@mail.gmail.com>
 <mfqqdt$9c3$1@ger.gmane.org>
Message-ID: <CANDiX9+6Lu6uUn7ecZ4acACwsGH6pphN8TNSDPiaNgbH-tgr=A@mail.gmail.com>

On Sun, Apr 5, 2015 at 3:06 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 05/04/15 04:45, boB Stepp wrote:
>
>>>>> He could have done it in various other ways too:
>>>>>
>>>>> eg.
>>>>> lambda : all(print('Hello lambda world!'), sys.exit() )
>
>
>> Well, now I am curious as to why the "all" form evaluates BOTH
>> elements. Apparently it does not apply the short-circuit logic we have
>> been discussing, or it would stop evaluating after the print statement
>> return.  Why is that?
>
>
> Because I didn't really think the example through properly.
> I just grabbed the first thing I could think of that would
> evaluate both functions... As Cameron has shown, a much more
> elegant solution is just to use a tuple as the body of
> the lambda.

Not to worry, Alan! This gave me an opportunity to read up on and
learn more about all() and any(), which I had not encountered
previously.  Also, much has been clarified about the details of how
and when things get evaluated for various approaches to these lambda
expressions. Many thanks!

-- 
boB

From narci.venturini at gmail.com  Sun Apr  5 16:12:32 2015
From: narci.venturini at gmail.com (Narci Edson Venturini)
Date: Sun, 5 Apr 2015 11:12:32 -0300
Subject: [Tutor] Matrix bug
Message-ID: <CAOMLp6CNRU98hPrUFTvzSXy1E_uRqVomHwz4hoYP0sksNZrRZA@mail.gmail.com>

The next code has an unexpected result:

>>>a=3*[3*[0]]
>>>a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>>a[0][0]=1
>>>a
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

The code assigned to "1" a(0,0), a(1,0) and a(2,0).

It was expected: [[1, 0, 0], [0, 0, 0], [0, 0, 0]]

When the followind code is ran, them the correct result is obtained:

>>>a=[[0 for i in range(3)] for j in range(3)]
>>>>>>a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>>a[0][0]=1
>>>a
 [[1, 0, 0], [0, 0, 0], [0, 0, 0]]

So, what is wrong ?

Best Regars,



Narci
__________________
Narci Edson Venturini
(19) 99733-8420

From solomon.vimal at gmail.com  Sun Apr  5 15:39:02 2015
From: solomon.vimal at gmail.com (Solomon Vimal)
Date: Sun, 5 Apr 2015 09:39:02 -0400
Subject: [Tutor] Python dir(handle) function acts weird
Message-ID: <CAA-TRN9LCs975Xj1FhYPH5VbZnFMvhxQ7v9ertxZk_BVmqGwXw@mail.gmail.com>

Hi,
I have two versions of the same software S4.1 and S5, say - they are
treated as COM handles.
When I use methodsview in MATLAB to see the list of methods in both, I get
more or less the same function list, but in Python, when I use dir(s4.1) I
get the identical list to MATLAB methodsview, but dir(s5) is a subset of
the list. This is weird behavior I thought.

Does anyone know what is wrong here? Please let me know soon.

Thanks a lot!
Solomon.

Solomon Vimal
(+1)9198690115

From alan.gauld at btinternet.com  Sun Apr  5 23:36:13 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 05 Apr 2015 22:36:13 +0100
Subject: [Tutor] Python dir(handle) function acts weird
In-Reply-To: <CAA-TRN9LCs975Xj1FhYPH5VbZnFMvhxQ7v9ertxZk_BVmqGwXw@mail.gmail.com>
References: <CAA-TRN9LCs975Xj1FhYPH5VbZnFMvhxQ7v9ertxZk_BVmqGwXw@mail.gmail.com>
Message-ID: <mfs9sc$648$1@ger.gmane.org>

On 05/04/15 14:39, Solomon Vimal wrote:
> Hi,
> I have two versions of the same software S4.1 and S5, say - they are
> treated as COM handles.
> When I use methodsview in MATLAB to see the list of methods in both, I get
> more or less the same function list, but in Python, when I use dir(s4.1) I
> get the identical list to MATLAB methodsview, but dir(s5) is a subset of
> the list. This is weird behavior I thought.
>
> Does anyone know what is wrong here? Please let me know soon.


Sorry I can't help, but its not really a Python question so much
as a Windows interface issue.

You don't say how you are accessing the COM objects but ctypes
and PyWin32 are both addressed by the Python windows mailing list.
I suggest you might get a more comprehensive reply there.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From emile at fenx.com  Sun Apr  5 23:43:15 2015
From: emile at fenx.com (Emile van Sebille)
Date: Sun, 05 Apr 2015 14:43:15 -0700
Subject: [Tutor] Matrix bug
In-Reply-To: <CAOMLp6CNRU98hPrUFTvzSXy1E_uRqVomHwz4hoYP0sksNZrRZA@mail.gmail.com>
References: <CAOMLp6CNRU98hPrUFTvzSXy1E_uRqVomHwz4hoYP0sksNZrRZA@mail.gmail.com>
Message-ID: <mfsabe$etm$1@ger.gmane.org>

On 4/5/2015 7:12 AM, Narci Edson Venturini wrote:
> The next code has an unexpected result:
>
>>>> a=3*[3*[0]]

a now contains three references to the same object, hence the results 
you show below.

You can create three distinct objects as follows:

 >>> a = [ [0,0,0] for i in (0,1,2) ]
 >>> a[1][1]=1
 >>> a
[[0, 0, 0], [0, 1, 0], [0, 0, 0]]
 >>>

hth,

Emile



>>>> a
> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>>> a[0][0]=1
>>>> a
> [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
>
> The code assigned to "1" a(0,0), a(1,0) and a(2,0).
>
> It was expected: [[1, 0, 0], [0, 0, 0], [0, 0, 0]]
>
> When the followind code is ran, them the correct result is obtained:
>
>>>> a=[[0 for i in range(3)] for j in range(3)]
>>>>>>> a
> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>>> a[0][0]=1
>>>> a
>   [[1, 0, 0], [0, 0, 0], [0, 0, 0]]
>
> So, what is wrong ?
>
> Best Regars,
>
>
>
> Narci
> __________________
> Narci Edson Venturini
> (19) 99733-8420
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



From alan.gauld at btinternet.com  Sun Apr  5 23:46:51 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 05 Apr 2015 22:46:51 +0100
Subject: [Tutor] Matrix bug
In-Reply-To: <CAOMLp6CNRU98hPrUFTvzSXy1E_uRqVomHwz4hoYP0sksNZrRZA@mail.gmail.com>
References: <CAOMLp6CNRU98hPrUFTvzSXy1E_uRqVomHwz4hoYP0sksNZrRZA@mail.gmail.com>
Message-ID: <mfsagb$gvq$1@ger.gmane.org>

On 05/04/15 15:12, Narci Edson Venturini wrote:
> The next code has an unexpected result:
>
>>>> a=3*[3*[0]]

Note that this makes three references to
the list of 3 references to 0.
In other words you reference the same list 3 times.
So when you change the first copy you change the
other 2 also.

Put another way:

 >>> mylist = [0,0,0]
 >>> a = 3 * [mylist]

'a' now contains 3 references to mylist, making
4 references altogether to the same list object.
If I change the list via any of them it will
change in all the places it is referenced:

 >>> mylist[0] = 1   # replace a zero with a one
 >>> mylist
[1, 0, 0]
 >>> a
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

> When the followind code is ran, them the correct result is obtained:
>
>>>> a=[[0 for i in range(3)] for j in range(3)]

This created 3 new lists. In fact you could simplify it to:

a = [[0,0,0] for i in range(3)]

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From steve at pearwood.info  Mon Apr  6 02:38:16 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 6 Apr 2015 10:38:16 +1000
Subject: [Tutor] Matrix bug
In-Reply-To: <CAOMLp6CNRU98hPrUFTvzSXy1E_uRqVomHwz4hoYP0sksNZrRZA@mail.gmail.com>
References: <CAOMLp6CNRU98hPrUFTvzSXy1E_uRqVomHwz4hoYP0sksNZrRZA@mail.gmail.com>
Message-ID: <20150406003815.GT25453@ando.pearwood.info>

On Sun, Apr 05, 2015 at 11:12:32AM -0300, Narci Edson Venturini wrote:
> The next code has an unexpected result:
> 
> >>>a=3*[3*[0]]
> >>>a
> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
> >>>a[0][0]=1
> >>>a
> [[1, 0, 0], [1, 0, 0], [1, 0, 0]]

It isn't obvious, and it is *very* common for people to run into this 
and be confused, but that is actually working by design. The * operator 
for lists does not copy the list items, it makes multiple references to 
it. Let's have a look at an example. We start with an arbitrary object:

py> class X: pass
...
py> x = X()
py> print(x)
<__main__.X object at 0xb7a9d92c>

Printing the object x shows us the memory location of x: 0xb7a9d92c. Now 
let us put it in a list, and replicate it:

py> mylist = [x]*3
py> print(mylist)
[<__main__.X object at 0xb7a9d92c>, <__main__.X object at 0xb7a9d92c>, 
<__main__.X object at 0xb7a9d92c>]


Do you see how *all three* list items have the same memory location? 
Rather than get three different X objects, we have the same object, 
repeated three times. So these two lines are essentially identical:

    mylist = [x]*3
    mylist = [x, x, x]


Now, in practice, sometimes that makes a difference, and sometimes it 
doesn't. If you use an int or a str, it makes no difference:

py> mylist = [1]*5
py> mylist
[1, 1, 1, 1, 1]

Let's look at their ID numbers and see that they are identical:

py> for item in mylist:
...     print(id(item))
...
136560640
136560640
136560640
136560640
136560640

So it is the same int object repeated five times, not five different 
objects. But that doesn't matter, since there is no way to change the 
value of the object: ints are immutable, and 1 is always 1. You can only 
*replace* the object with a new object:

py> mylist[0] = 2
py> print(mylist)
[2, 1, 1, 1, 1]


Now let's do it again with a list of lists:


py> mylist = [[]]*5
py> mylist
[[], [], [], [], []]
py> for item in mylist:
...     print(id(item))
...
3081330988
3081330988
3081330988
3081330988
3081330988


So you can see, we now have the same list repeated five times, not five 
different lists. If we *replace* one of the items, using = assignment, 
everything behaves as expected:

py> mylist[0] = [1,2,3]  # Replace the first item.
py> print(mylist)
[[1, 2, 3], [], [], [], []]


But if we modify one of the items, you may be surprised:

py> mylist[1].append(999)  # Change the second item in place.
py> print(mylist)
[[1, 2, 3], [999], [999], [999], [999]]



The solution to this "gotcha" is to avoid list multiplication except for 
immutable objects like ints and strings. So to get a 3 x 3 array of all 
zeroes, I would write:

py> array = [[0]*3 for i in range(3)]
py> print(array)
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
py> array[0][1] += 1
py> print(array)
[[0, 1, 0], [0, 0, 0], [0, 0, 0]]


-- 
Steve

From steve at pearwood.info  Mon Apr  6 02:43:58 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 6 Apr 2015 10:43:58 +1000
Subject: [Tutor] Python dir(handle) function acts weird
In-Reply-To: <CAA-TRN9LCs975Xj1FhYPH5VbZnFMvhxQ7v9ertxZk_BVmqGwXw@mail.gmail.com>
References: <CAA-TRN9LCs975Xj1FhYPH5VbZnFMvhxQ7v9ertxZk_BVmqGwXw@mail.gmail.com>
Message-ID: <20150406004358.GU25453@ando.pearwood.info>

On Sun, Apr 05, 2015 at 09:39:02AM -0400, Solomon Vimal wrote:
> Hi,
> I have two versions of the same software S4.1 and S5, say - they are
> treated as COM handles.
> When I use methodsview in MATLAB to see the list of methods in both, I get
> more or less the same function list, but in Python, when I use dir(s4.1) I
> get the identical list to MATLAB methodsview, but dir(s5) is a subset of
> the list. This is weird behavior I thought.
> 
> Does anyone know what is wrong here? Please let me know soon.

I have no idea what you are talking about.

What are S4.1 and S5? What sort of software are they?

What is methodsview in MATLAB?

How are you using the same software in MATLAB and Python?

You cannot run dir(s4.1) in Python, that's a syntax error. So what are 
you actually doing?

Please COPY and PASTE the exact code you are using, don't summarise it, 
and especially don't write it out from memory. Remember that we cannot 
see your computer, nor do we understand the background to your question. 
Don't assume we are MATLAB experts.


-- 
Steve

From robertvstepp at gmail.com  Mon Apr  6 16:54:47 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 6 Apr 2015 09:54:47 -0500
Subject: [Tutor] Why is it invalid syntax to have a particular dictionary
	value as an argument?
Message-ID: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>

Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit
(Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> d = {'n': 'Print me!'}
>>> d
{'n': 'Print me!'}
>>> d['n']
'Print me!'
>>> def func(d['n']):
SyntaxError: invalid syntax
>>> def func(d):
        print d['n']

>>> func(d)
Print me!

The plain text does not show it, but in the invalid syntax the "[" is
highlighted red.

Why is it invalid syntax to pass a particular dictionary value in a
function? Or does it require a different form to do so?

Thanks!

-- 
boB

From joel.goldstick at gmail.com  Mon Apr  6 17:20:24 2015
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Mon, 6 Apr 2015 11:20:24 -0400
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
Message-ID: <CAPM-O+x1pZj+1SoPakODq6uPTWbYyz6F5XTy6MXYiRunUXJzzA@mail.gmail.com>

On Mon, Apr 6, 2015 at 10:54 AM, boB Stepp <robertvstepp at gmail.com> wrote:
> Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit
> (Intel)] on win32
> Type "copyright", "credits" or "license()" for more information.
>>>> d = {'n': 'Print me!'}
>>>> d
> {'n': 'Print me!'}
>>>> d['n']
> 'Print me!'
>>>> def func(d['n']):
> SyntaxError: invalid syntax
>>>> def func(d):
>         print d['n']
>
>>>> func(d)
> Print me!
>
> The plain text does not show it, but in the invalid syntax the "[" is
> highlighted red.
>
> Why is it invalid syntax to pass a particular dictionary value in a
> function? Or does it require a different form to do so?
>

Here is another example:

>>> def f(6):
  File "<stdin>", line 1
    def f(6):
          ^
SyntaxError: invalid syntax
>>>

You can't pass a value as a parameter to a  function definition.  You
need to provide a name.  The actual value is supplied when you call
the function

> Thanks!
>
> --
> boB
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Joel Goldstick
http://joelgoldstick.com

From joel.goldstick at gmail.com  Mon Apr  6 17:38:37 2015
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Mon, 6 Apr 2015 11:38:37 -0400
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <CAPM-O+x1pZj+1SoPakODq6uPTWbYyz6F5XTy6MXYiRunUXJzzA@mail.gmail.com>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
 <CAPM-O+x1pZj+1SoPakODq6uPTWbYyz6F5XTy6MXYiRunUXJzzA@mail.gmail.com>
Message-ID: <CAPM-O+xC9gm2p9RsEEXTcaiTb_tJ3AmjK4fo3EMrA9P2dVestQ@mail.gmail.com>

On Mon, Apr 6, 2015 at 11:20 AM, Joel Goldstick
<joel.goldstick at gmail.com> wrote:
> On Mon, Apr 6, 2015 at 10:54 AM, boB Stepp <robertvstepp at gmail.com> wrote:
>> Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit
>> (Intel)] on win32
>> Type "copyright", "credits" or "license()" for more information.
>>>>> d = {'n': 'Print me!'}
>>>>> d
>> {'n': 'Print me!'}
>>>>> d['n']
>> 'Print me!'
>>>>> def func(d['n']):
>> SyntaxError: invalid syntax
>>>>> def func(d):
>>         print d['n']
>>
>>>>> func(d)
>> Print me!
>>
>> The plain text does not show it, but in the invalid syntax the "[" is
>> highlighted red.
>>
>> Why is it invalid syntax to pass a particular dictionary value in a
>> function? Or does it require a different form to do so?
>>
>
> Here is another example:
>
>>>> def f(6):
>   File "<stdin>", line 1
>     def f(6):
>           ^
> SyntaxError: invalid syntax
>>>>
>
> You can't pass a value as a parameter to a  function definition.  You
> need to provide a name.  The actual value is supplied when you call
> the function

The python.org site has this:
https://docs.python.org/2/reference/compound_stmts.html#function-definitions

>
>> Thanks!
>>
>> --
>> boB
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> https://mail.python.org/mailman/listinfo/tutor
>
>
>
> --
> Joel Goldstick
> http://joelgoldstick.com



-- 
Joel Goldstick
http://joelgoldstick.com

From davea at davea.name  Mon Apr  6 18:31:16 2015
From: davea at davea.name (Dave Angel)
Date: Mon, 06 Apr 2015 12:31:16 -0400
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
Message-ID: <5522B4D4.7060500@davea.name>

On 04/06/2015 10:54 AM, boB Stepp wrote:
> Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit
> (Intel)] on win32
> Type "copyright", "credits" or "license()" for more information.
>>>> d = {'n': 'Print me!'}
>>>> d
> {'n': 'Print me!'}
>>>> d['n']
> 'Print me!'
>>>> def func(d['n']):
> SyntaxError: invalid syntax
>>>> def func(d):
>          print d['n']
>
>>>> func(d)
> Print me!
>
> The plain text does not show it, but in the invalid syntax the "[" is
> highlighted red.
>
> Why is it invalid syntax to pass a particular dictionary value in a
> function? Or does it require a different form to do so?

You're getting confused between defining a function and calling one.

For Python 2.7, see:
 
https://docs.python.org/2/reference/compound_stmts.html#function-definitions


When defining a function, you provide (not pass) the formal parameters, 
and they must be simple names.  Those names will end up being local 
variables when the function is finally called.

(The only sort-of exception to this in 2.7 is when you define a default 
argument to a function.  In that case, the parameter still must be a 
valid python variable name, but the default value can be an arbitrary 
expression, as long as it's valid at the time of function definition.)


Once the function is being called, then you can use an arbitrary 
expression for your argument.  The results of that expression is bound 
to the formal parameter specified above.

Further reading:
https://docs.python.org/2/faq/programming.html#faq-argument-vs-parameter
https://docs.python.org/2/glossary.html#term-parameter
https://docs.python.org/2/glossary.html#term-argument


Now, it's possible that what you're trying to do is something that can 
be accomplished some other way.  So please elaborate on your purpose in 
using the syntax you did.  Or supply a small program that shows a 
function being defined and called, that would give meaning to the syntax 
you're trying.
-- 
DaveA

From robertvstepp at gmail.com  Mon Apr  6 18:43:11 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 6 Apr 2015 11:43:11 -0500
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <5522B4D4.7060500@davea.name>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
 <5522B4D4.7060500@davea.name>
Message-ID: <CANDiX9L78So4z+mOUBvGF_oegDXL40PTc5jqkyb=TSAzxQZV3A@mail.gmail.com>

Thanks, Joel! Thanks, Dave!

On Mon, Apr 6, 2015 at 11:31 AM, Dave Angel <davea at davea.name> wrote:

[...]

> Now, it's possible that what you're trying to do is something that can be
> accomplished some other way.  So please elaborate on your purpose in using
> the syntax you did.  Or supply a small program that shows a function being
> defined and called, that would give meaning to the syntax you're trying.

I was breaking down longer functions into smaller ones. Along the way
I noticed I was passing an entire dictionary from one function to
another. I only needed to pass one particular value, not the whole
dictionary, so that is how I got into the issue I asked about. Once
you and Joel responded it was *obvious*. A bunch of years ago, it
would have been *obvious* and I never would have asked the question in
the first place. This is easy enough to correct now that I realize
what I was doing.

-- 
boB

From davea at davea.name  Mon Apr  6 19:54:58 2015
From: davea at davea.name (Dave Angel)
Date: Mon, 06 Apr 2015 13:54:58 -0400
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <CANDiX9L78So4z+mOUBvGF_oegDXL40PTc5jqkyb=TSAzxQZV3A@mail.gmail.com>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>	<5522B4D4.7060500@davea.name>
 <CANDiX9L78So4z+mOUBvGF_oegDXL40PTc5jqkyb=TSAzxQZV3A@mail.gmail.com>
Message-ID: <5522C872.7000003@davea.name>

On 04/06/2015 12:43 PM, boB Stepp wrote:

>
> I was breaking down longer functions into smaller ones. Along the way
> I noticed I was passing an entire dictionary from one function to
> another. I only needed to pass one particular value, not the whole
> dictionary, so that is how I got into the issue I asked about.

Just to reinforce something you probably know well, passing a dictionary 
takes no more memory or time than passing an item from that dictionary. 
  The real choice is whether the called function should dealing with a 
single item or with a dictionary.  It would have a different name in 
each case, and a different set of reuse possibilities.

I know the following example abuses the dictionary, using it as though 
it were an instance of class Person.  It's just what popped into my head.

def check_person(person):
     if person["name"] in list_of_preferred:
          do_something...
          return True
     return False

def check_name(name):
     if name in list_of_preferred:
          do_something...
          return True
     return False

In the first case, the function would be able use other elements of the 
dictionary, like "email_address" or "phone_number".

In the second case, you could call the function from someplace that has 
only names, and isn't worried about what dict the name might be part of.


-- 
DaveA

From anubhav1691 at gmail.com  Mon Apr  6 12:46:29 2015
From: anubhav1691 at gmail.com (Anubhav Yadav)
Date: Mon, 6 Apr 2015 16:16:29 +0530
Subject: [Tutor] Need some help with setuptools for my project.
Message-ID: <CA+Jf9AEDpx48MNub0ZVAryE-HHPNsZ_NkZ6d=zFprFFEM6r6ow@mail.gmail.com>

Hi,

I am new to python and still trying to get my concepts clear with respect
to standard practices in python. I wrote a script which fetches the latest
cricket scores from the internet and sends desktop notifications using
pynotify. The project, initially supported both python2 as well as python3,
but I realized it is very difficult to keep up with the errors. So I
migrated the project to python2.

Now I wanted to make my script robust such that it could be installed
easily by the users. I broke up my script in logical modules and added them
all under root directory with the name of the project.

Here is how the source tree looks now:

|-- LICENSE
|-- README.md
|-- requirements.txt
|-- scorer
|   |-- app.py
|   |-- fetch_scores.py
|   |-- __init__.py
|   |-- __main__.py
|   |-- notification.py
|   |-- system.py
|   `-- ui.py
`-- setup.py

Where scorer is the name of the project. Here are the contents of the
requirements.txt file:

scorer
requests==2.6.0
beautifulsoup4==4.3.2

And here is my setup.py

from setuptools import setup

def readme():
    with open('README.md') as f:
        return f.read()

setup(
    name = 'scorer',
    version = 0.1,
    description = 'A simple script to show desktop notifications for
cricket scores',
    long_description = readme(),
    url = 'https://github.com/neo1691/scorer.py',
    author = 'Anubhav Yadav',
    author_email = 'anubhav1691 at gmail.com',
    license = 'GPLv2',
    packages = ['scorer'],
    install_requires=[
          'requests',
          'beautifulsoup4',
      ],
    zip_safe = False
        )

When I run ``python setup.py build``, It gives me the following output:

running build
running build_py
creating build
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/scorer
copying scorer/ui.py -> build/lib.linux-x86_64-2.7/scorer
copying scorer/__init__.py -> build/lib.linux-x86_64-2.7/scorer
copying scorer/system.py -> build/lib.linux-x86_64-2.7/scorer
copying scorer/fetch_scores.py -> build/lib.linux-x86_64-2.7/scorer
copying scorer/__main__.py -> build/lib.linux-x86_64-2.7/scorer
copying scorer/app.py -> build/lib.linux-x86_64-2.7/scorer
copying scorer/notification.py -> build/lib.linux-x86_64-2.7/scorer

It creates a build directory with the above files, and I have no idea what
to do with them. How to use it? Or how to test my app without installing
it.

If I then run ``sudo python setup.py install``, it gives me a lot of output
but one of the lines is:
Installed /usr/lib/python2.7/site-packages/scorer-0.1-py2.7.egg

A few more directories are created in my project directory, build, dist,
scorer.egg-info etc. Yet I still have no idea how to run my app.

I can run my app from the root of the project directory using ``python -m
scorer`` since I have called my main() function using the __main__.py file.

Can someone help me figure out how can I package my project according to
setuptools format? Also can someone tell me how to un-install the project
from systemwide after running ``sudo python setup.py install``?

Any help would be greatly appreciated. I apologize if my question does not
belongs to this mailing list. My project is hosted on github[1].

Thank you.

[1] https://github.com/neo1691/scorer.py

-- 
Regards,
Anubhav Yadav
KPIT Technologies,
Pune.

From cybervigilante at gmail.com  Mon Apr  6 16:05:27 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Mon, 6 Apr 2015 07:05:27 -0700
Subject: [Tutor] failed filter result
Message-ID: <CALRAYNWhxecU752e=tahyo9-JURiLHsVOxXT+Pbz6fUzYErKZA@mail.gmail.com>

Why did this fail where it did? It failed at listing the result of the
filter of a word list, but I figured if it failed, it would have done so at
the filter.

>>> words = open('5desk.txt').readlines()
>>> k = [word.rstrip for word in words]
>>> len(k)
61406
>>> p = filter(lambda word: len(word) > 10, k)
>>> p
<filter object at 0x01992F30>
>>> list(p)
Traceback (most recent call last):
  File "<string>", line 301, in runcode
  File "<interactive input>", line 1, in <module>
  File "<interactive input>", line 1, in <lambda>
TypeError: object of type 'builtin_function_or_method' has no len()

-- 
Jim

I can't think of a clever tagline today, so just imagine I said something
clever.

From timomlists at gmail.com  Mon Apr  6 20:06:39 2015
From: timomlists at gmail.com (Timo)
Date: Mon, 06 Apr 2015 20:06:39 +0200
Subject: [Tutor] failed filter result
In-Reply-To: <CALRAYNWhxecU752e=tahyo9-JURiLHsVOxXT+Pbz6fUzYErKZA@mail.gmail.com>
References: <CALRAYNWhxecU752e=tahyo9-JURiLHsVOxXT+Pbz6fUzYErKZA@mail.gmail.com>
Message-ID: <5522CB2F.3070402@gmail.com>

Op 06-04-15 om 16:05 schreef Jim Mooney:
> Why did this fail where it did? It failed at listing the result of the
> filter of a word list, but I figured if it failed, it would have done so at
> the filter.
>
>>>> words = open('5desk.txt').readlines()
>>>> k = [word.rstrip for word in words]
Your problem is in the above line. Have this example:

 >>> words = ["foo", "bar", "spam", "eggs"]
 >>> k = [word.rstrip for word in words]
 >>> k
[<built-in method rstrip of str object at 0x7fd1f3cb1538>, <built-in 
method rstrip of str object at 0x7fd1f3cb1880>, <built-in method rstrip 
of str object at 0x7fd1f3cb1148>, <built-in method rstrip of str object 
at 0x7fd1f3cda3e8>]

Looks very similar to your TypeError later on!

Let's see what's wrong:
 >>> "foo".rstrip
<built-in method rstrip of str object at 0x7fd1f3cb1538>

Still the same...

Let's go further:
 >>> "foo".rstrip()
'foo'

Looks much better!
So the problem is you're storing the rstrip function instead of calling 
it and store the result. A big difference.
The fix is very easy, just call rstrip in your list comprehension:
k = [word.rstrip() for word in words]

A little tip: errors like these are easy to debug by printing your 
values. If you printed k before continuing it wouldn't have happened.

Timo

>>>> len(k)
> 61406
>>>> p = filter(lambda word: len(word) > 10, k)
>>>> p
> <filter object at 0x01992F30>
>>>> list(p)
> Traceback (most recent call last):
>    File "<string>", line 301, in runcode
>    File "<interactive input>", line 1, in <module>
>    File "<interactive input>", line 1, in <lambda>
> TypeError: object of type 'builtin_function_or_method' has no len()
>


From alan.gauld at btinternet.com  Mon Apr  6 20:12:58 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 06 Apr 2015 19:12:58 +0100
Subject: [Tutor] failed filter result
In-Reply-To: <CALRAYNWhxecU752e=tahyo9-JURiLHsVOxXT+Pbz6fUzYErKZA@mail.gmail.com>
References: <CALRAYNWhxecU752e=tahyo9-JURiLHsVOxXT+Pbz6fUzYErKZA@mail.gmail.com>
Message-ID: <mfuib9$slg$1@ger.gmane.org>

On 06/04/15 15:05, Jim Mooney wrote:
> Why did this fail where it did? It failed at listing the result of the
> filter of a word list, but I figured if it failed, it would have done so at
> the filter.
>
>>>> words = open('5desk.txt').readlines()
>>>> k = [word.rstrip for word in words]

Notice that you are not calling rstrip here. You are creating a list 
with as many references to word.rstrip as there are words. This is 
almost certainly not what you want. You need to add the parens.

>>>> p = filter(lambda word: len(word) > 10, k)
>>>> list(p)
> Traceback (most recent call last):
>    File "<string>", line 301, in runcode
>    File "<interactive input>", line 1, in <module>
>    File "<interactive input>", line 1, in <lambda>
> TypeError: object of type 'builtin_function_or_method' has no len()

This is because you are passing a list of function
references rather than stripped words.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Mon Apr  6 20:16:27 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 06 Apr 2015 19:16:27 +0100
Subject: [Tutor] Need some help with setuptools for my project.
In-Reply-To: <CA+Jf9AEDpx48MNub0ZVAryE-HHPNsZ_NkZ6d=zFprFFEM6r6ow@mail.gmail.com>
References: <CA+Jf9AEDpx48MNub0ZVAryE-HHPNsZ_NkZ6d=zFprFFEM6r6ow@mail.gmail.com>
Message-ID: <mfuihq$5mr$1@ger.gmane.org>

On 06/04/15 11:46, Anubhav Yadav wrote:

> Any help would be greatly appreciated. I apologize if my question does not
> belongs to this mailing list. My project is hosted on github[1].

Using the setup tools and creating/installing projects seems
close enough to standard library functions that its on topic
so far as I'm concerned :-)

Sorry I don't really know the answers to your questions though!

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From emile at fenx.com  Mon Apr  6 21:20:37 2015
From: emile at fenx.com (Emile van Sebille)
Date: Mon, 06 Apr 2015 12:20:37 -0700
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
Message-ID: <mfumc0$p9b$1@ger.gmane.org>

On 4/6/2015 7:54 AM, boB Stepp wrote:
> Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit
> (Intel)] on win32
> Type "copyright", "credits" or "license()" for more information.
>>>> d = {'n': 'Print me!'}
>>>> d
> {'n': 'Print me!'}
>>>> d['n']
> 'Print me!'
>>>> def func(d['n']):
> SyntaxError: invalid syntax
>>>> def func(d):
>          print d['n']
>
>>>> func(d)
> Print me!
>
> The plain text does not show it, but in the invalid syntax the "[" is
> highlighted red.
>
> Why is it invalid syntax to pass a particular dictionary value in a
> function? Or does it require a different form to do so?

Maybe this form helps:

Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
 >>> d = {'a':'123'}
 >>> def func(s=d['a']):
...   print s
...
 >>> func()
123

Emile




From davea at davea.name  Mon Apr  6 21:42:40 2015
From: davea at davea.name (Dave Angel)
Date: Mon, 06 Apr 2015 15:42:40 -0400
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <mfumc0$p9b$1@ger.gmane.org>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
 <mfumc0$p9b$1@ger.gmane.org>
Message-ID: <5522E1B0.9070904@davea.name>

On 04/06/2015 03:20 PM, Emile van Sebille wrote:
> On 4/6/2015 7:54 AM, boB Stepp wrote:
>> Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit
>> (Intel)] on win32
>> Type "copyright", "credits" or "license()" for more information.
>>>>> d = {'n': 'Print me!'}
>>>>> d
>> {'n': 'Print me!'}
>>>>> d['n']
>> 'Print me!'
>>>>> def func(d['n']):
>> SyntaxError: invalid syntax
>>>>> def func(d):
>>          print d['n']
>>
>>>>> func(d)
>> Print me!
>>
>> The plain text does not show it, but in the invalid syntax the "[" is
>> highlighted red.
>>
>> Why is it invalid syntax to pass a particular dictionary value in a
>> function? Or does it require a different form to do so?
>
> Maybe this form helps:
>
> Python 2.7.6 (default, Mar 22 2014, 22:59:56)
> [GCC 4.8.2] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> d = {'a':'123'}
>  >>> def func(s=d['a']):
> ...   print s
> ...
>  >>> func()
> 123
>

Only if you know that nobody is going to be changing d.

 >>> d = {"a":"123"}
 >>> def func(s=d["a"]):
...     print s
...
 >>> d["a"] = "new value"
 >>> func()
123
 >>>


-- 
DaveA

From breamoreboy at yahoo.co.uk  Mon Apr  6 22:08:13 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Mon, 06 Apr 2015 21:08:13 +0100
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <mfumc0$p9b$1@ger.gmane.org>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
 <mfumc0$p9b$1@ger.gmane.org>
Message-ID: <mfup3h$llg$1@ger.gmane.org>

On 06/04/2015 20:20, Emile van Sebille wrote:
> On 4/6/2015 7:54 AM, boB Stepp wrote:
>> Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit
>> (Intel)] on win32
>> Type "copyright", "credits" or "license()" for more information.
>>>>> d = {'n': 'Print me!'}
>>>>> d
>> {'n': 'Print me!'}
>>>>> d['n']
>> 'Print me!'
>>>>> def func(d['n']):
>> SyntaxError: invalid syntax
>>>>> def func(d):
>>          print d['n']
>>
>>>>> func(d)
>> Print me!
>>
>> The plain text does not show it, but in the invalid syntax the "[" is
>> highlighted red.
>>
>> Why is it invalid syntax to pass a particular dictionary value in a
>> function? Or does it require a different form to do so?
>
> Maybe this form helps:
>
> Python 2.7.6 (default, Mar 22 2014, 22:59:56)
> [GCC 4.8.2] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> d = {'a':'123'}
>  >>> def func(s=d['a']):
> ...   print s
> ...
>  >>> func()
> 123
>
> Emile
>

Dreadful advice.  There have always have been and always will be 
questions from newbies as they do not understand how this construct 
works in Python.  Please *DO NOT* put such things forward.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From dylanlee.evans95 at gmail.com  Mon Apr  6 22:22:59 2015
From: dylanlee.evans95 at gmail.com (Dylan Evans)
Date: Mon, 6 Apr 2015 21:22:59 +0100
Subject: [Tutor] Need some help with setuptools for my project.
In-Reply-To: <mailman.1438.1428342995.12924.tutor@python.org>
References: <mailman.1438.1428342995.12924.tutor@python.org>
Message-ID: <etPan.5522eb23.69dfcc5a.1ab4@Dylans-MBP>

On 6 April 2015 at 18:56:57, tutor-request at python.org (tutor-request at python.org) wrote:
> Any help would be greatly appreciated. I apologize if my question does not
> belongs to this mailing list. My project is hosted on github[1].
>  
> Thank you.
>  
> [1] https://github.com/neo1691/scorer.py

You might consider packaging your project as a script so that it can be run by the user from the command line. See:?https://docs.python.org/2/distutils/setupscript.html#installing-scripts

Provided that you add something like #!/usr/bin/python to the top of scorer.py, 'python setup.py install? will make it executable and move it to /usr/local/bin (on mac anyway) so that it can be run from the command line without the need to be in a specific directory or use the python command. You can even drop the .py from the file name so the user would just type in ?scorer? to start the script.

If you?d like to make your script available to the wider community, you can put it on PyPI. See:?https://docs.python.org/2/distutils/packageindex.html

?

Dylan Evans

From anubhav1691 at gmail.com  Tue Apr  7 10:31:21 2015
From: anubhav1691 at gmail.com (Anubhav Yadav)
Date: Tue, 7 Apr 2015 14:01:21 +0530
Subject: [Tutor] Need some help with setuptools for my project.
In-Reply-To: <etPan.5522eb23.69dfcc5a.1ab4@Dylans-MBP>
References: <mailman.1438.1428342995.12924.tutor@python.org>
 <etPan.5522eb23.69dfcc5a.1ab4@Dylans-MBP>
Message-ID: <CA+Jf9AEeTnwXSv-rKKe7mZUb55GkurTAMqvPg1JRvfaeNiCZPA@mail.gmail.com>

You might consider packaging your project as a script so that it can be run
> by the user from the command line. See:
> https://docs.python.org/2/distutils/setupscript.html#installing-scripts
>
> Provided that you add something like #!/usr/bin/python to the top of
> scorer.py, 'python setup.py install? will make it executable and move it to
> /usr/local/bin (on mac anyway) so that it can be run from the command line
> without the need to be in a specific directory or use the python command.
> You can even drop the .py from the file name so the user would just type in
> ?scorer? to start the script.
>
>
Hi, as you can see my project doesn't have any single script. It is now
made of many modules, and the app.py imports all the modules and executes
them in the main() function. I also have an __main__.py where I call the
main() function. I can run my project from the root of the directory using
``python -m scorer``. But if I use setuptools and install python using
``sudo python setup.py install``, setuptools says that my script is
installed but I don't know how to run it?



> If you?d like to make your script available to the wider community, you
> can put it on PyPI. See:
> https://docs.python.org/2/distutils/packageindex.html
>

I would love to upload my script to PyPi, but first I need to figure out if
my project is getting installed properly using setuptools or not.


-- 
Regards,
Anubhav Yadav

From emile at fenx.com  Tue Apr  7 17:57:16 2015
From: emile at fenx.com (Emile van Sebille)
Date: Tue, 07 Apr 2015 08:57:16 -0700
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <5522E1B0.9070904@davea.name>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
 <mfumc0$p9b$1@ger.gmane.org> <5522E1B0.9070904@davea.name>
Message-ID: <mg0uqq$1tu$1@ger.gmane.org>

On 4/6/2015 12:42 PM, Dave Angel wrote:
> On 04/06/2015 03:20 PM, Emile van Sebille wrote:
<snip>
>> Python 2.7.6 (default, Mar 22 2014, 22:59:56)
>> [GCC 4.8.2] on linux2
>> Type "help", "copyright", "credits" or "license" for more information.
>>  >>> d = {'a':'123'}
>>  >>> def func(s=d['a']):
>> ...   print s
>> ...
>>  >>> func()
>> 123
>>
>
> Only if you know that nobody is going to be changing d.

Clearly my example avoids the pitfalls of a changing d.  :)

>  >>> d = {"a":"123"}
>  >>> def func(s=d["a"]):
> ...     print s
> ...
>  >>> d["a"] = "new value"
>  >>> func()
> 123

Good point -- I forgot about setting default parameters at compile time.

 >>> d={'a':'123'}
 >>> def func(s=d):print s['a']
...
 >>> func()
123
 >>>
 >>> d['a']='456'
 >>> func()
456
 >>>




From anubhav1691 at gmail.com  Tue Apr  7 13:00:43 2015
From: anubhav1691 at gmail.com (Anubhav Yadav)
Date: Tue, 7 Apr 2015 16:30:43 +0530
Subject: [Tutor] Need some help with setuptools for my project.
In-Reply-To: <etPan.5523b6eb.d3b6d1.1ab4@Dylans-MBP>
References: <mailman.1438.1428342995.12924.tutor@python.org>
 <etPan.5522eb23.69dfcc5a.1ab4@Dylans-MBP>
 <CA+Jf9AEeTnwXSv-rKKe7mZUb55GkurTAMqvPg1JRvfaeNiCZPA@mail.gmail.com>
 <etPan.5523b6eb.d3b6d1.1ab4@Dylans-MBP>
Message-ID: <CA+Jf9AFrKZALb-FakO17Zu85UWdq2iHbwOk5n16MPktazaZiUg@mail.gmail.com>

>
> On your GitHub repository, you have a single file, scorer.py. I think that
> this is a better approach in this instance than the multiple file approach
> you have now taken (see below).
>

I am sorry I linked the master repository. See the structureCode branch[1].

>
> > setuptools says that my script is installed but I don't know how to run
> it?
>
> setuptools will have installed your module to site-packages so that other
> developers can import it to use in writing their own code. However, your
> code doesn?t provide anything for developers e.g. new functions, classes
> etc. so this isn?t really want you want. Rather, your code should be run by
> the end user, the cricket fan. From the first link I gave:
>
> ?Python modules...are usually not run by themselves but imported by
> scripts. Scripts are files containing Python source code, intended to be
> started from the command line"
>
> The latter sounds much more like your situation, so I recommend you do it
> that way. Scripts like this should be single files, hence my recommendation
> to use one file.
>
> Hope that helps,
>

This certainly helps, if you see the new link that I have given this time,
you will notice that I have an app.py in my project dir, and it has the
main() function. I have called the main function in __main__.py. This[2]
blog post tells me that you can run your app using ``python -m scorer``
from the root directory of the project, and indeed I am able to run my
scorer app like this.

Now my question is  how can I use setup tools so that users can just run
"scorer" from the command line and the my script(which was installed before
by setuptools) will start?

[1] https://github.com/neo1691/scorer.py/tree/structureCode
[2] http://blog.habnab.it/blog/2013/07/21/python-packages-and-you/

-- 
Regards,
Anubhav Yadav
KPIT Technologies,
Pune.

From anubhav1691 at gmail.com  Tue Apr  7 17:50:54 2015
From: anubhav1691 at gmail.com (Anubhav Yadav)
Date: Tue, 7 Apr 2015 21:20:54 +0530
Subject: [Tutor] Need some help with setuptools for my project.
In-Reply-To: <etPan.5523df51.3e61e272.1ab4@Dylans-MBP>
References: <mailman.1438.1428342995.12924.tutor@python.org>
 <etPan.5522eb23.69dfcc5a.1ab4@Dylans-MBP>
 <CA+Jf9AEeTnwXSv-rKKe7mZUb55GkurTAMqvPg1JRvfaeNiCZPA@mail.gmail.com>
 <etPan.5523b6eb.d3b6d1.1ab4@Dylans-MBP>
 <CA+Jf9AFrKZALb-FakO17Zu85UWdq2iHbwOk5n16MPktazaZiUg@mail.gmail.com>
 <etPan.5523df51.3e61e272.1ab4@Dylans-MBP>
Message-ID: <CA+Jf9AGfXpPDoDKQoWscew-qVfDhg9uHPcyGyouGWhowAWKXMA@mail.gmail.com>

I apologise, my method was for distutils, not setuptools. I get the two
> muddled. The mechanism for creating a console script like you describe with
> setuptools is described here[1]. The post you linked also has a section on
> it under the heading ?Executable scripts?. It allows for the multiple file
> approach you have.
>
> This is it, here's what I did:

I edited my setup.py and added the following:
  entry_points={
        'console_scripts':[
            'scorer = scorer.app.main'
            ]
        },

As the main function is in scorer/app.py.

Now after running sudo python setup.py install, I can see that there is a
scorer binary installed in my system, but when I run that, I get the
following error.

Traceback (most recent call last):
  File "/usr/bin/scorer", line 9, in <module>
    load_entry_point('scorer==0.1', 'console_scripts', 'scorer')()
  File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line
546, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line
2666, in load_entry_point
    return ep.load()
  File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line
2339, in load
    return self.resolve()
  File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line
2345, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
ImportError: No module named main

I am this close I guess!

As an aside, I would also suggest that you look at PEP8, the Python style
> guide[3]. Your code should really conform to it as much as possible.
>

And thanks a lot for giving me the PEP8 link, it will be helpful.

>
> [1]
> https://pythonhosted.org/setuptools/setuptools.html#automatic-script-creation
> [2] https://www.python.org/dev/peps/pep-0008/
>
>
> ?
>
> Dylan Evans
>



-- 
Regards,
Anubhav Yadav
KPIT Technologies,
Pune.

From fraghide at hotmail.it  Tue Apr  7 22:52:07 2015
From: fraghide at hotmail.it (Francesca Ghidelli)
Date: Tue, 7 Apr 2015 22:52:07 +0200
Subject: [Tutor] help
Message-ID: <DUB131-W377C15F86E0AE02415E4E4A1FD0@phx.gbl>

Hello,First of all, i'm not trying to learn how to program with Python. I use Blender for my project, Blender 2.49b uses Python262. when i try to export the mesh from Blender to an other program, python doesn't work and show the error like the screenshot in annex. I've just  installed numpy 1.3.0, but i tried different version before , it shows always the same error.I have Windows 7...could you find a solution for my problem?

 		 	   		  

From alan.gauld at btinternet.com  Wed Apr  8 01:23:07 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 08 Apr 2015 00:23:07 +0100
Subject: [Tutor] help
In-Reply-To: <DUB131-W377C15F86E0AE02415E4E4A1FD0@phx.gbl>
References: <DUB131-W377C15F86E0AE02415E4E4A1FD0@phx.gbl>
Message-ID: <mg1osq$j9v$1@ger.gmane.org>

On 07/04/15 21:52, Francesca Ghidelli wrote:
> Hello,First of all, i'm not trying to learn how to program with Python.

OK. So how exactly are you using Python?

 > I use Blender for my project, Blender 2.49b uses Python262.

This is a list for folks learning Python so we don't necessarily
know much about Blender. as I understand it Python is Blenders
macro language. Is that what you are doing? Running a macro?

>  i try to export the mesh from Blender to an other program,

What's a mesh? How does python feature in the export?

> python doesn't work and show the error like the screenshot in annex.

This is a mailing list. Many email gateways don't allow attachments.
Your' got lost. Please copy the full error message into your post.
If you can copy the code too - or at least the bit the error refers
to - that would help - remember we don't know much about Blender.

> I've just  installed numpy 1.3.0, but i tried different version
 > before , it shows always the same error.

Again, not too many here know numpy, it's not part of standard Python. 
How does it fit with Blender and your problem? If the error is a numpy 
error there is a numpy (or sciPy) list that might know more.

There is also a mailing list on gmane.org that is dedicated to Python on 
Blender:

gmane.comp.video.blender.python

You could try asking there. They should at least understand what you
are talking about.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From cs at zip.com.au  Wed Apr  8 02:11:30 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Wed, 8 Apr 2015 10:11:30 +1000
Subject: [Tutor] Need some help with setuptools for my project.
In-Reply-To: <CA+Jf9AGfXpPDoDKQoWscew-qVfDhg9uHPcyGyouGWhowAWKXMA@mail.gmail.com>
References: <CA+Jf9AGfXpPDoDKQoWscew-qVfDhg9uHPcyGyouGWhowAWKXMA@mail.gmail.com>
Message-ID: <20150408001130.GA106@cskk.homeip.net>

On 07Apr2015 21:20, Anubhav Yadav <anubhav1691 at gmail.com> wrote:
>I apologise, my method was for distutils, not setuptools. I get the two
>> muddled. The mechanism for creating a console script like you describe with
>> setuptools is described here[1]. The post you linked also has a section on
>> it under the heading ?Executable scripts?. It allows for the multiple file
>> approach you have.
>>
>> This is it, here's what I did:
>
>I edited my setup.py and added the following:
>  entry_points={
>        'console_scripts':[
>            'scorer = scorer.app.main'
>            ]
>        },

My megacli module installs its "mcli" script like this:

    'entry_points': {
      'console_scripts': [
          'mcli = cs.app.megacli:main',
          ],

Note the ":" before main, not ".".

Cheers,
Cameron Simpson <cs at zip.com.au>

I think... Therefore I ride.  I ride... Therefore I am.
        - Mark Pope <erectus at yarrow.wt.uwa.edu.au>

From robertvstepp at gmail.com  Wed Apr  8 03:42:48 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 7 Apr 2015 20:42:48 -0500
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <5522C872.7000003@davea.name>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
 <5522B4D4.7060500@davea.name>
 <CANDiX9L78So4z+mOUBvGF_oegDXL40PTc5jqkyb=TSAzxQZV3A@mail.gmail.com>
 <5522C872.7000003@davea.name>
Message-ID: <CANDiX9K6uqBB3ji28v3yyTb+L-2wYoDkmfQn_rQ0LtuhBEJ-Ow@mail.gmail.com>

On Mon, Apr 6, 2015 at 12:54 PM, Dave Angel <davea at davea.name> wrote:
> On 04/06/2015 12:43 PM, boB Stepp wrote:
>
>>
>> I was breaking down longer functions into smaller ones. Along the way
>> I noticed I was passing an entire dictionary from one function to
>> another. I only needed to pass one particular value, not the whole
>> dictionary, so that is how I got into the issue I asked about.
>
>
> Just to reinforce something you probably know well, passing a dictionary
> takes no more memory or time than passing an item from that dictionary...

One thing about Python that I must keep reminding myself is that its
identifiers store references to objects, not the actual objects
themselves.

> ... The
> real choice is whether the called function should dealing with a single item
> or with a dictionary.  It would have a different name in each case, and a
> different set of reuse possibilities.

In my actual code, I am trying to take advantage of these ideas.

boB

From robertvstepp at gmail.com  Wed Apr  8 04:16:23 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 7 Apr 2015 21:16:23 -0500
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <5522E1B0.9070904@davea.name>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
 <mfumc0$p9b$1@ger.gmane.org> <5522E1B0.9070904@davea.name>
Message-ID: <CANDiX9L5LeSjNpy4DB5hia0G-toLp7b2ViwoZAtLB5oNs4m3dg@mail.gmail.com>

On Mon, Apr 6, 2015 at 2:42 PM, Dave Angel <davea at davea.name> wrote:
> On 04/06/2015 03:20 PM, Emile van Sebille wrote:
>>
>> On 4/6/2015 7:54 AM, boB Stepp wrote:
>>>

[...]

>>
>> Maybe this form helps:
>>
>> Python 2.7.6 (default, Mar 22 2014, 22:59:56)
>> [GCC 4.8.2] on linux2
>> Type "help", "copyright", "credits" or "license" for more information.
>>  >>> d = {'a':'123'}
>>  >>> def func(s=d['a']):
>> ...   print s
>> ...
>>  >>> func()
>> 123
>>
>
> Only if you know that nobody is going to be changing d.
>
>>>> d = {"a":"123"}
>>>> def func(s=d["a"]):
> ...     print s
> ...
>>>> d["a"] = "new value"
>>>> func()
> 123

Despite Mark's warning, I feel I must see if I understand what is going on here.

Switching to Py 3.4 since I am now at home:

Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600
64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> d = {'a': '123'}
>>> def func(s=d['a']):
              print(s)
              print(d['a'])

>>> func()
123
123
>>> d['a'] = 'new value'
>>> func()
123
new value

I added an additional print to the function to show the dictionary
entry's behavior.

First, my current understanding is that this form of the function does
not object to the presence of d['a'] in its parameter list because s
is the real parameter, d['a'] is its default value, but s is not
actually evaluated until run time.

But once s *is* evaluated, it stores a reference to the original
object, '123'. Changing d['a'] outside the function to a new value
does not alter the fact that s is storing the very same reference to
'123'. After reassigning d['a'] to point to the new object 'new
value', a new call to func() shows s still referencing the original
object and d['a'] referencing the new object. Is my comprehension of
these details correct? If yes, this is why I must constantly remind
myself that identifiers store references to objects, and that some
objects are mutable and some aren't, and these Python facts of life
are constantly challenging my old FORTRAN <= 77 ways of thinking...
~(:>))

-- 
boB

From cs at zip.com.au  Wed Apr  8 06:23:19 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Wed, 8 Apr 2015 14:23:19 +1000
Subject: [Tutor] Need some help with setuptools for my project.
In-Reply-To: <CA+Jf9AFqJ01N7XbEKfQ=5MYh8RG9umM32Y4NcKKEMmf_K4Cweg@mail.gmail.com>
References: <CA+Jf9AFqJ01N7XbEKfQ=5MYh8RG9umM32Y4NcKKEMmf_K4Cweg@mail.gmail.com>
Message-ID: <20150408042319.GA42297@cskk.homeip.net>

On 08Apr2015 08:53, Anubhav Yadav <anubhav1691 at gmail.com> wrote:
>>Note the ":" before main, not ".".
>
>That's it, that fixed the problem. Now I have a scorer binary.

No, you have a "scorer" executable which is a script. A "binary" is a loadable 
machine code file.

>Thanks. A
>couple of more questions!
>
>1) If I have install_requires in setup.py, then do I need requirements.txt?

Probably not? I don't use this yet myself.

>2) Can I run ``python setup.py install`` or ``python setup.py develop``
>with root privileges? Just to test the app first?

Yes, but I would discourage it. It is too easy to tread on your platform's 
supplier packages this way. That can be bad, especially if you break something 
important for your OS.

Instead, I would advocate making a virtualenv iin your home directory into 
which you install your packages. You can make as many as you like.

After you've made a virtualenv, running the "pip" it supplies will install into 
the virtualenv. Much safer, and you can do it all as yourself.

Cheers,
Cameron Simpson <cs at zip.com.au>

I made this letter longer than usual because I lack the time to make it
shorter.        - Pascal

From cs at zip.com.au  Wed Apr  8 06:43:22 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Wed, 8 Apr 2015 14:43:22 +1000
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <CANDiX9L5LeSjNpy4DB5hia0G-toLp7b2ViwoZAtLB5oNs4m3dg@mail.gmail.com>
References: <CANDiX9L5LeSjNpy4DB5hia0G-toLp7b2ViwoZAtLB5oNs4m3dg@mail.gmail.com>
Message-ID: <20150408044322.GA67698@cskk.homeip.net>

On 07Apr2015 21:16, boB Stepp <robertvstepp at gmail.com> wrote:
>Despite Mark's warning, I feel I must see if I understand what is going on here.
>
>Switching to Py 3.4 since I am now at home:
>
>Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600
>64 bit (AMD64)] on win32
>Type "copyright", "credits" or "license()" for more information.
>>>> d = {'a': '123'}
>>>> def func(s=d['a']):
>              print(s)
>              print(d['a'])
>
>>>> func()
>123
>123
>>>> d['a'] = 'new value'
>>>> func()
>123
>new value
>
>I added an additional print to the function to show the dictionary
>entry's behavior.
>
>First, my current understanding is that this form of the function does
>not object to the presence of d['a'] in its parameter list because s
>is the real parameter, d['a'] is its default value, but s is not
>actually evaluated until run time.

Yes and no.

Yes to "s is the real parameter, d['a'] is its default value".

No to "s is not actually evaluated until run time".

When you _define_ the function, the _current_ value of d['a'] is stashed in the 
function definition as the default value.

When you _call_ the function, and omit the 's' parameter, the default value is 
used.

However, that value was _computed_ when the function was compiled: the function 
definition does not keep "d['a']" around for evaluation, instead that 
expression is evaluated when you define the function, and the reference to the 
resulting value kept around. That is thus '123'.

So when you go:

  d['a'] = 'new value'

the contents of the "d" dictionary have changed. But all that has happened is 
that the reference to '123' is no longer in the dictionary; instead a reference 
to 'new value' is in the dictionary.

When you call "func()" the name "s" is bound to the default value, which is the 
'123' as computed at function definition time. And it prints that. Of course, 
when you print "d['a']" it must evaluate that then, and finds 'new value'.

This is one reason why the common idion for default values looks like this:

  def func(s=None):
    if s is None:
      s = ... compute default here ...

Of course, the default is often a constant or some value computed earlier.

Cheers,
Cameron Simpson <cs at zip.com.au>

I think... Therefore I ride.  I ride... Therefore I am.
        - Mark Pope <erectus at yarrow.wt.uwa.edu.au>

From anubhav1691 at gmail.com  Wed Apr  8 05:23:11 2015
From: anubhav1691 at gmail.com (Anubhav Yadav)
Date: Wed, 8 Apr 2015 08:53:11 +0530
Subject: [Tutor] Need some help with setuptools for my project.
In-Reply-To: <20150408001130.GA106@cskk.homeip.net>
References: <CA+Jf9AGfXpPDoDKQoWscew-qVfDhg9uHPcyGyouGWhowAWKXMA@mail.gmail.com>
 <20150408001130.GA106@cskk.homeip.net>
Message-ID: <CA+Jf9AFqJ01N7XbEKfQ=5MYh8RG9umM32Y4NcKKEMmf_K4Cweg@mail.gmail.com>

Note the ":" before main, not ".".
>

That's it, that fixed the problem. Now I have a scorer binary. Thanks. A
couple of more questions!

1) If I have install_requires in setup.py, then do I need requirements.txt?
2) Can I run ``python setup.py install`` or ``python setup.py develop``
with root privileges? Just to test the app first?



-- 
Regards,
Anubhav Yadav
Pune.

From anubhav1691 at gmail.com  Wed Apr  8 08:28:54 2015
From: anubhav1691 at gmail.com (Anubhav Yadav)
Date: Wed, 8 Apr 2015 11:58:54 +0530
Subject: [Tutor] Need some help with setuptools for my project.
In-Reply-To: <20150408042319.GA42297@cskk.homeip.net>
References: <CA+Jf9AFqJ01N7XbEKfQ=5MYh8RG9umM32Y4NcKKEMmf_K4Cweg@mail.gmail.com>
 <20150408042319.GA42297@cskk.homeip.net>
Message-ID: <CA+Jf9AGQt-cA5E2ZH05XaPtLyFXnbLhgVG+HA_fwG-7yS3Xswg@mail.gmail.com>

> Instead, I would advocate making a virtualenv iin your home directory into
> which you install your packages. You can make as many as you like.
>
> After you've made a virtualenv, running the "pip" it supplies will install
> into the virtualenv. Much safer, and you can do it all as yourself.
>

Thanks a lot, I would now spend some time learning virtualenv! This has
really helped me. Thank you everyone again for helping me out. I would
bring the thread alive again if I am stuck somewhere.

Cheers

Regards,
Anubhav Yadav
Pune.

From cybervigilante at gmail.com  Wed Apr  8 02:52:19 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Tue, 7 Apr 2015 17:52:19 -0700
Subject: [Tutor] migrating python to a new machine
Message-ID: <CALRAYNVbzUF_HbiPNET5TGmmm82GwR41KmoAm+BSqb2TnJmhmg@mail.gmail.com>

General question. I'm thinking of moving to a new machine although I hate
to abandon trusty XP. Will I have to reinstall all my pip installed modules
or can I just copy the site-packages directory? And if so, is anything else
needed, such as where pip keeps its uninstall info?

Finally, is there such a thing as a standalone Python? I use a number of
standalone programs so it seems to me it should be possible.

-- 
Jim

"Stop, Harold! That bagel has radishes!"
"Thank God, Mary - you've saved me again!"

From alan.gauld at btinternet.com  Wed Apr  8 09:50:53 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 08 Apr 2015 08:50:53 +0100
Subject: [Tutor] migrating python to a new machine
In-Reply-To: <CALRAYNVbzUF_HbiPNET5TGmmm82GwR41KmoAm+BSqb2TnJmhmg@mail.gmail.com>
References: <CALRAYNVbzUF_HbiPNET5TGmmm82GwR41KmoAm+BSqb2TnJmhmg@mail.gmail.com>
Message-ID: <mg2mkt$58q$1@ger.gmane.org>

On 08/04/15 01:52, Jim Mooney wrote:
> General question. I'm thinking of moving to a new machine although I hate
> to abandon trusty XP.

If you plan to stick with Windows check out ClassicShell.
You'll feel right at home. :-)

> Will I have to reinstall all my pip installed modules
> or can I just copy the site-packages directory?

I think that will work. You will need to reinstall Python
itself to get the registry set up but I think the stuff
that Python installs is safe to just copy across.

> Finally, is there such a thing as a standalone Python?

I'm not sure what you mean by that. But if its a Python
that you can install/run on a USB stick, say, then yes,
there are several options available. Google is your
friend...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Wed Apr  8 09:54:19 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 08 Apr 2015 08:54:19 +0100
Subject: [Tutor] Need some help with setuptools for my project.
In-Reply-To: <CA+Jf9AGQt-cA5E2ZH05XaPtLyFXnbLhgVG+HA_fwG-7yS3Xswg@mail.gmail.com>
References: <CA+Jf9AFqJ01N7XbEKfQ=5MYh8RG9umM32Y4NcKKEMmf_K4Cweg@mail.gmail.com>
 <20150408042319.GA42297@cskk.homeip.net>
 <CA+Jf9AGQt-cA5E2ZH05XaPtLyFXnbLhgVG+HA_fwG-7yS3Xswg@mail.gmail.com>
Message-ID: <mg2mra$58q$2@ger.gmane.org>

On 08/04/15 07:28, Anubhav Yadav wrote:

> really helped me. Thank you everyone again for helping me out. I would
> bring the thread alive again if I am stuck somewhere.

Please don't!

If it's a new problem start a new thread with new subject line.
1) The old thread will be miles back in the history and
    invisible to anyone using a threaded reader.
2) Anyone searching the archives will find it difficult
    to see your new issue buried inside a previous thread


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From zachary.ware+pytut at gmail.com  Wed Apr  8 13:44:42 2015
From: zachary.ware+pytut at gmail.com (Zachary Ware)
Date: Wed, 8 Apr 2015 06:44:42 -0500
Subject: [Tutor] migrating python to a new machine
In-Reply-To: <CALRAYNVbzUF_HbiPNET5TGmmm82GwR41KmoAm+BSqb2TnJmhmg@mail.gmail.com>
References: <CALRAYNVbzUF_HbiPNET5TGmmm82GwR41KmoAm+BSqb2TnJmhmg@mail.gmail.com>
Message-ID: <CAKJDb-Ocw8LmZnWh9+mG=pHdYp6ZP0KwCR0BChA9f7jGd-Bh1w@mail.gmail.com>

On Apr 8, 2015 3:39 AM, "Jim Mooney" <cybervigilante at gmail.com> wrote:
>
> General question. I'm thinking of moving to a new machine although I hate
> to abandon trusty XP. Will I have to reinstall all my pip installed
modules
> or can I just copy the site-packages directory? And if so, is anything
else
> needed, such as where pip keeps its uninstall info?

The safest method would probably be to do `pip freeze > requirements.txt`,
copy the requirements.txt file to the new machine, and run `pip install -r
requirements.txt` there.  That way you definitely get everything (and you
can save the requirements file for backup purposes).

> Finally, is there such a thing as a standalone Python? I use a number of
> standalone programs so it seems to me it should be possible.

Do you mean like a "portable" app, that doesn't write to the registry and
keeps everything in one folder?  You can try PortablePython; I used it some
several years ago and it seemed to work fine (but that was when I was just
starting with Python).

Hope this helps,
--
Zach

From davea at davea.name  Wed Apr  8 14:44:22 2015
From: davea at davea.name (Dave Angel)
Date: Wed, 08 Apr 2015 08:44:22 -0400
Subject: [Tutor] Why is it invalid syntax to have a particular
 dictionary value as an argument?
In-Reply-To: <CANDiX9L5LeSjNpy4DB5hia0G-toLp7b2ViwoZAtLB5oNs4m3dg@mail.gmail.com>
References: <CANDiX9LHv6RULsyw2eprJA4F3OA4d+E4C-Jxsngo3eQe7gc5rg@mail.gmail.com>
 <mfumc0$p9b$1@ger.gmane.org> <5522E1B0.9070904@davea.name>
 <CANDiX9L5LeSjNpy4DB5hia0G-toLp7b2ViwoZAtLB5oNs4m3dg@mail.gmail.com>
Message-ID: <552522A6.9010406@davea.name>

On 04/07/2015 10:16 PM, boB Stepp wrote:
>
> Despite Mark's warning, I feel I must see if I understand what is going on here.
>
> Switching to Py 3.4 since I am now at home:
>
> Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600
> 64 bit (AMD64)] on win32
> Type "copyright", "credits" or "license()" for more information.
>>>> d = {'a': '123'}
>>>> def func(s=d['a']):
>                print(s)
>                print(d['a'])
>
>>>> func()
> 123
> 123
>>>> d['a'] = 'new value'
>>>> func()
> 123
> new value
>
> I added an additional print to the function to show the dictionary
> entry's behavior.
>
> First, my current understanding is that this form of the function does
> not object to the presence of d['a'] in its parameter list because s
> is the real parameter, d['a'] is its default value, but s is not
> actually evaluated until run time.

s is not evaluated till the print statement.  s is *bound* at function 
call time.  And at that time it is either bound to the object passed by 
the caller, or to the default object.

In a simple assignment statement:
    a = b + 6

the expression on the right is evaluated.  The name on the left is not 
evaluated, it is bound to.  So we say
    "a is bound to the result of the expression b+6"

>
> But once s *is* evaluated, it stores  a reference to the original

   s is bound to the expression ''default_object'', which is to say it 
copies the same reference that the default object stored earlier.  So it 
is bound to '123'

> object, '123'. Changing d['a'] outside the function to a new value
> does not alter the fact that s is storing the very same reference to
> '123'. After reassigning d['a'] to point to the new object 'new
> value', a new call to func() shows s still referencing the original
> object and d['a'] referencing the new object. Is my comprehension of
> these details correct? If yes, this is why I must constantly remind
> myself that identifiers store references to objects, and that some
> objects are mutable and some aren't, and these Python facts of life
> are constantly challenging my old FORTRAN <= 77 ways of thinking...
> ~(:>))
>


-- 
DaveA

From cybervigilante at gmail.com  Wed Apr  8 17:25:45 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Wed, 8 Apr 2015 08:25:45 -0700
Subject: [Tutor] migrating python to a new machine
In-Reply-To: <CAKJDb-Ocw8LmZnWh9+mG=pHdYp6ZP0KwCR0BChA9f7jGd-Bh1w@mail.gmail.com>
References: <CALRAYNVbzUF_HbiPNET5TGmmm82GwR41KmoAm+BSqb2TnJmhmg@mail.gmail.com>
 <CAKJDb-Ocw8LmZnWh9+mG=pHdYp6ZP0KwCR0BChA9f7jGd-Bh1w@mail.gmail.com>
Message-ID: <CALRAYNVEUeg5EBy911HOvdzZKOh6xp3D6WTiuPOCAdyRktPePA@mail.gmail.com>

Thanks, I'll try Portable. It's got py3 and comes with a bunch of useful
stuff already installed:

http://portablepython.com/wiki/PortablePython3.2.5.1/

Python 3.2.5.1

    PyScripter v2.5.3
    NymPy 1.7.1
    SciPy 0.12.0
    Matplotlib 1.2.1
    PyWin32 218
    NetworkX v1.7
    Lxml 2.3
    PySerial 2.5
    PyODBC 3.0.2
    PyQt 4.9.6-1
    IPython 0.13.1
    Pandas 0.11.0




On 8 April 2015 at 04:44, Zachary Ware <zachary.ware+pytut at gmail.com> wrote:

> On Apr 8, 2015 3:39 AM, "Jim Mooney" <cybervigilante at gmail.com> wrote:
> >
> > General question. I'm thinking of moving to a new machine although I hate
> > to abandon trusty XP. Will I have to reinstall all my pip installed
> modules
> > or can I just copy the site-packages directory? And if so, is anything
> else
> > needed, such as where pip keeps its uninstall info?
>
> The safest method would probably be to do `pip freeze > requirements.txt`,
> copy the requirements.txt file to the new machine, and run `pip install -r
> requirements.txt` there.  That way you definitely get everything (and you
> can save the requirements file for backup purposes).
>
> > Finally, is there such a thing as a standalone Python? I use a number of
> > standalone programs so it seems to me it should be possible.
>
> Do you mean like a "portable" app, that doesn't write to the registry and
> keeps everything in one folder?  You can try PortablePython; I used it some
> several years ago and it seemed to work fine (but that was when I was just
> starting with Python).
>
> Hope this helps,
> --
> Zach
>



-- 
Jim

"Stop, Harold! That bagel has radishes!"
"Thank God, Mary - you've saved me again!"

From akleider at sonic.net  Thu Apr  9 04:44:39 2015
From: akleider at sonic.net (Alex Kleider)
Date: Wed, 08 Apr 2015 19:44:39 -0700
Subject: [Tutor] pip install lxml fails
Message-ID: <e36efeaaa5940120829fba845dcd9dd5@sonic.net>

In the process of trying to learn about web scraping
(http://docs.python-guide.org/en/latest/scenarios/scrape/)
I tried to pip install lxml.

Can anyone suggest a remedy?

The output goes on for many pages and the resulting .pip/pip.log
file is almost 900 lines long
but the main meat of the failure seems to be in the following:

(env)alex at t61p:~/P3env/declination.d$ pip install lxml
Downloading/unpacking lxml
   Downloading lxml-3.4.2.tar.gz (3.5MB): 3.5MB downloaded
   Running setup.py (path:/home/alex/P3env/env/build/lxml/setup.py) 
egg_info for package lxml
     Building lxml version 3.4.2.
     Building without Cython.
     Using build configuration of libxslt 1.1.28
     /usr/lib/python3.4/distutils/dist.py:260: UserWarning: Unknown 
distribution option: 'bugtrack_url'
       warnings.warn(msg)

     warning: no previously-included files found matching '*.py'
Installing collected packages: lxml
   Running setup.py install for lxml
     Building lxml version 3.4.2.
     Building without Cython.
     Using build configuration of libxslt 1.1.28
     building 'lxml.etree' extension
     i686-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall 
-Wstrict-prototypes -g -fstack-protector --param=ssp-buffer-size=4 
-Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fPIC 
-I/usr/include/libxml2 
-I/home/alex/P3env/env/build/lxml/src/lxml/includes 
-I/usr/include/python3.4m -I/home/alex/P3env/env/include/python3.4m -c 
src/lxml/lxml.etree.c -o build/temp.linux-i686-3.4/src/lxml/lxml.etree.o 
-w
     src/lxml/lxml.etree.c:8:22: fatal error: pyconfig.h: No such file or 
directory
      #include "pyconfig.h"
                           ^
     compilation terminated.
     /usr/lib/python3.4/distutils/dist.py:260: UserWarning: Unknown 
distribution option: 'bugtrack_url'
       warnings.warn(msg)
     error: command 'i686-linux-gnu-gcc' failed with exit status 1
     Complete output from command /home/alex/P3env/env/bin/python3 -c 
"import setuptools, 
tokenize;__file__='/home/alex/P3env/env/build/lxml/setup.py';exec(compile(getattr(tokenize, 
'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 
'exec'))" install --record /tmp/pip-sknxo73w-record/install-record.txt 
--single-version-externally-managed --compile --install-headers 
/home/alex/P3env/env/include/site/python3.4:
......

From akleider at sonic.net  Thu Apr  9 17:29:46 2015
From: akleider at sonic.net (Alex Kleider)
Date: Thu, 09 Apr 2015 08:29:46 -0700
Subject: [Tutor] pip install lxml fails
In-Reply-To: <20150409140818.GB6451@test-chamber-1.castopulence.org>
References: <e36efeaaa5940120829fba845dcd9dd5@sonic.net>
 <20150409140818.GB6451@test-chamber-1.castopulence.org>
Message-ID: <aa9fe9337423a4d0411239370c226758@sonic.net>

On 2015-04-09 07:08, Brandon McCaig wrote:
> I'm a python newbie, but it looks to me like your compiler cannot
> find your header files, and in particular pyconfig.h.
> 
> I tried searching my system and found a file with that name at
> these locations:
> 
>     /home/bambams/src/pyenv/versions/2.7.9/include/python2.7/pyconfig.h
>     
> /home/bambams/src/pyenv/versions/3.4.2/include/python3.4m/pyconfig.h
>     /usr/include/python2.6/pyconfig.h
>     /usr/include/python2.7/pyconfig.h
>     /usr/include/python3.2mu/pyconfig.h
> 
> Based on that I am assuming that you should have a pyconfig.h in
> either /usr/include/python3.4m or
> /home/alex/P3env/env/include/python3.4m. I would probably start
> there to verify that I have that header file in a location where
> it's expected (-I flags in the above command, or system include
> directories). If not then I would wonder why...
> 
> Regards,

Thank you very much for looking into this.

I have corresponding files in /usr/include for 2.7 but not for 3*:
alex at t61p:~/P3env/env$ ls -ld /usr/include/python*
drwxr-xr-x 2 root root 4096 Apr  8 19:05 /usr/include/python2.7

alex at t61p:~/P3env/env$ ls
bin  lib
Nothing in the env file (generated by virtualenv.)

My Ubuntu 14.04 system comes with Python3 by default so it does exist:
alex at t61p:~/P3env/env$ which python3
/usr/bin/python3
It's a mystery why it doesn't come with the corresponding include 
directory.

I'm guessing this is a system level problem that can probably only be 
solved by someone at Ubuntu or one of the lxml maintainers.

Thanks again,
Alex


From stefan_ml at behnel.de  Thu Apr  9 18:11:25 2015
From: stefan_ml at behnel.de (Stefan Behnel)
Date: Thu, 09 Apr 2015 18:11:25 +0200
Subject: [Tutor] pip install lxml fails
In-Reply-To: <aa9fe9337423a4d0411239370c226758@sonic.net>
References: <e36efeaaa5940120829fba845dcd9dd5@sonic.net>
 <20150409140818.GB6451@test-chamber-1.castopulence.org>
 <aa9fe9337423a4d0411239370c226758@sonic.net>
Message-ID: <mg68be$7bd$1@ger.gmane.org>

Alex Kleider schrieb am 09.04.2015 um 17:29:
> On 2015-04-09 07:08, Brandon McCaig wrote:
>> I'm a python newbie, but it looks to me like your compiler cannot
>> find your header files, and in particular pyconfig.h.
>>
>> I tried searching my system and found a file with that name at
>> these locations:
>>
>>     /home/bambams/src/pyenv/versions/2.7.9/include/python2.7/pyconfig.h
>>     /home/bambams/src/pyenv/versions/3.4.2/include/python3.4m/pyconfig.h
>>     /usr/include/python2.6/pyconfig.h
>>     /usr/include/python2.7/pyconfig.h
>>     /usr/include/python3.2mu/pyconfig.h
>>
>> Based on that I am assuming that you should have a pyconfig.h in
>> either /usr/include/python3.4m or
>> /home/alex/P3env/env/include/python3.4m. I would probably start
>> there to verify that I have that header file in a location where
>> it's expected (-I flags in the above command, or system include
>> directories). If not then I would wonder why...
> 
> I have corresponding files in /usr/include for 2.7 but not for 3*:
> alex at t61p:~/P3env/env$ ls -ld /usr/include/python*
> drwxr-xr-x 2 root root 4096 Apr  8 19:05 /usr/include/python2.7
> 
> alex at t61p:~/P3env/env$ ls
> bin  lib
> Nothing in the env file (generated by virtualenv.)
> 
> My Ubuntu 14.04 system comes with Python3 by default so it does exist:
> alex at t61p:~/P3env/env$ which python3
> /usr/bin/python3
> It's a mystery why it doesn't come with the corresponding include directory.
> 
> I'm guessing this is a system level problem that can probably only be
> solved by someone at Ubuntu or one of the lxml maintainers.

It's solved already. :)

All you need to do is install the "-dev" package that goes with your Python
installation, e.g. "python3-dev" should match Python 3.4 in current Ubuntu
releases.

The reason why it's in a separate package is that many people actually
don't need this, e.g. when they only install plain Python packages or use
the Ubuntu provided binary packages that they can install via apt (e.g.
"sudo apt-get install python-lxml").

Stefan



From akleider at sonic.net  Thu Apr  9 21:49:16 2015
From: akleider at sonic.net (Alex Kleider)
Date: Thu, 09 Apr 2015 12:49:16 -0700
Subject: [Tutor] pip install lxml fails
In-Reply-To: <mg68be$7bd$1@ger.gmane.org>
References: <e36efeaaa5940120829fba845dcd9dd5@sonic.net>
 <20150409140818.GB6451@test-chamber-1.castopulence.org>
 <aa9fe9337423a4d0411239370c226758@sonic.net> <mg68be$7bd$1@ger.gmane.org>
Message-ID: <957838078c7c686d7e635054e832eba5@sonic.net>

On 2015-04-09 09:11, Stefan Behnel wrote:

> It's solved already. :)
> 
> All you need to do is install the "-dev" package that goes with your 
> Python
> installation, e.g. "python3-dev" should match Python 3.4 in current 
> Ubuntu
> releases.
> 
> The reason why it's in a separate package is that many people actually
> don't need this, e.g. when they only install plain Python packages or 
> use
> the Ubuntu provided binary packages that they can install via apt (e.g.
> "sudo apt-get install python-lxml").

Thanks Brandon and Sefan.  It proved correct that I did not have 
python3-dev installed
.. but after intalling it, the pip install lxml still fails!

There's a huge amount of output but what follows might provide clues as 
to the current problem:

................

     /usr/lib/python3.4/distutils/dist.py:260: UserWarning: Unknown
distribution option: 'bugtrack_url'
       warnings.warn(msg)

     warning: no previously-included files found matching '*.py'
.......

Cleaning up...
Command /home/alex/P3env/env/bin/python3 -c "import setuptools,
tokenize;__file__='/home/alex/P3env/env/build/lxml/setup.py';exec(compile(getattr(tokenize,
'open', open)(__file__).read().replace('\r\n', '\n'), __file__,
'exec'))" install --record /tmp/pip-56yiw_ye-record/install-record.txt
--single-version-externally-managed --compile --install-headers
/home/alex/P3env/env/include/site/python3.4 failed with error code 1 in
/home/alex/P3env/env/build/lxml
Storing debug log for failure in /home/alex/.pip/pip.log


Looking at ~/.pip/pip.log
there seem to be hundreds of Skipping link ... unknown archive format:
.egg, .exe, lines typified by the following two:
     Skipping link 
https://pypi.python.org/packages/2.7/l/lxml/lxml-2.3beta1-py2.7-win32.egg#md5=4c0da2b308dd2cd0095de21c26647842 
(from https://pypi.python.org/simple/lxml/); unknown archive format: 
.egg
     Skipping link 
https://pypi.python.org/packages/2.7/l/lxml/lxml-2.3beta1.win32-py2.7.exe#md5=ea0224feed6f649cdb1ccb656ab91d81 
(from https://pypi.python.org/simple/lxml/); unknown archive format: 
.exe

Then it found some tar.gz links (103 of them to be exact)
Then "Ignoring link .." for bout 27 lines and finally
Some possibly useful information:

   Using version 3.4.2 (newest of versions: 3.4.2, 3.4.1, 3.4.0, 3.3.6, 
3.3.5, 3.3.4, 3.3.3, 3.3.2, 3.3.1, 3.3.0, 3.2.5, 3.2.4, 3.2.3, 3.2.2, 
3.2.1, 3.2.0, 3.1.2, 3.1.1, 3.1.0, 3.0.2, 3.0.1, 3.0, 2.3.6, 2.3.5, 
2.3.4, 2.3.3, 2.3.2, 2.3.1, 2.3, 2.2.8, 2.2.7, 2.2.6, 2.2.5, 2.2.4, 
2.2.3, 2.2.2, 2.2.1, 2.2, 2.1.5, 2.1.4, 2.1.3, 2.1.2, 2.1.1, 2.1, 
2.0.11, 2.0.10, 2.0.9, 2.0.8, 2.0.7, 2.0.6, 2.0.5, 2.0.4, 2.0.3, 2.0.2, 
2.0.1, 2.0, 1.3.6, 1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3, 1.2.1, 1.2, 1.1.2, 
1.1.1, 1.1, 1.0.4, 1.0.3, 1.0.2, 1.0.1, 1.0, 0.9.2, 0.9.1, 0.9)
   Downloading from URL 
https://pypi.python.org/packages/source/l/lxml/lxml-3.4.2.tar.gz#md5=429e5e771c4be0798923c04cb9739b4e 
(from https://pypi.python.org/simple/lxml/)
   Running setup.py (path:/home/alex/P3env/env/build/lxml/setup.py) 
egg_info for package lxml
     Building lxml version 3.4.2.
     Building without Cython.
     Using build configuration of libxslt 1.1.28
     running egg_info
     creating pip-egg-info/lxml.egg-info
     writing pip-egg-info/lxml.egg-info/PKG-INFO
     writing dependency_links to 
pip-egg-info/lxml.egg-info/dependency_links.txt
     writing top-level names to pip-egg-info/lxml.egg-info/top_level.txt
     writing requirements to pip-egg-info/lxml.egg-info/requires.txt
     writing manifest file 'pip-egg-info/lxml.egg-info/SOURCES.txt'
     /usr/lib/python3.4/distutils/dist.py:260: UserWarning: Unknown 
distribution option: 'bugtrack_url'
       warnings.warn(msg)
     warning: manifest_maker: standard file '-c' not found

..........

     i686-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall 
-Wstrict-prototypes -g -fstack-protector --param=ssp-buffer-size=4 
-Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fPIC 
-I/usr/include/libxml2 
-I/home/alex/P3env/env/build/lxml/src/lxml/includes 
-I/usr/include/python3.4m -I/home/alex/P3env/env/include/python3.4m -c 
src/lxml/lxml.etree.c -o build/temp.linux-i686-3.4/src/lxml/lxml.etree.o 
-w
     i686-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions 
-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-Bsymbolic-functions 
-Wl,-z,relro -g -fstack-protector --param=ssp-buffer-size=4 -Wformat 
-Werror=format-security -D_FORTIFY_SOURCE=2 
build/temp.linux-i686-3.4/src/lxml/lxml.etree.o -lxslt -lexslt -lxml2 
-lz -lm -o build/lib.linux-i686-3.4/lxml/etree.cpython-34m.so
     /usr/bin/ld: cannot find -lz
     collect2: error: ld returned 1 exit status
     /usr/lib/python3.4/distutils/dist.py:260: UserWarning: Unknown 
distribution option: 'bugtrack_url'
       warnings.warn(msg)
     error: command 'i686-linux-gnu-gcc' failed with exit status 1
     Complete output from command /home/alex/P3env/env/bin/python3 -c 
"import setuptools, 
tokenize;__file__='/home/alex/P3env/env/build/lxml/setup.py';exec(compile(getattr(tokenize, 
'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 
'exec'))" install --record /tmp/pip-56yiw_ye-record/install-record.txt 
--single-version-externally-managed --compile --install-headers 
/home/alex/P3env/env/include/site/python3.4:
     Building lxml version 3.4.2.

Building without Cython.

Using build configuration of libxslt 1.1.28

running install

running build

running build_py

creating build

..........


i686-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall 
-Wstrict-prototypes -g -fstack-protector --param=ssp-buffer-size=4 
-Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fPIC 
-I/usr/include/libxml2 
-I/home/alex/P3env/env/build/lxml/src/lxml/includes 
-I/usr/include/python3.4m -I/home/alex/P3env/env/include/python3.4m -c 
src/lxml/lxml.etree.c -o build/temp.linux-i686-3.4/src/lxml/lxml.etree.o 
-w

i686-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions 
-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-Bsymbolic-functions 
-Wl,-z,relro -g -fstack-protector --param=ssp-buffer-size=4 -Wformat 
-Werror=format-security -D_FORTIFY_SOURCE=2 
build/temp.linux-i686-3.4/src/lxml/lxml.etree.o -lxslt -lexslt -lxml2 
-lz -lm -o build/lib.linux-i686-3.4/lxml/etree.cpython-34m.so

/usr/bin/ld: cannot find -lz

collect2: error: ld returned 1 exit status

/usr/lib/python3.4/distutils/dist.py:260: UserWarning: Unknown 
distribution option: 'bugtrack_url'

   warnings.warn(msg)

error: command 'i686-linux-gnu-gcc' failed with exit status 1

----------------------------------------
Cleaning up...
   Removing temporary dir /home/alex/P3env/env/build...
Command /home/alex/P3env/env/bin/python3 -c "import setuptools, 
tokenize;__file__='/home/alex/P3env/env/build/lxml/setup.py';exec(compile(getattr(tokenize, 
'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 
'exec'))" install --record /tmp/pip-56yiw_ye-record/install-record.txt 
--single-version-externally-managed --compile --install-headers 
/home/alex/P3env/env/include/site/python3.4 failed with error code 1 in 
/home/alex/P3env/env/build/lxml
Exception information:
Traceback (most recent call last):
   File 
"/home/alex/P3env/env/lib/python3.4/site-packages/pip/basecommand.py", 
line 122, in main
     status = self.run(options, args)
   File 
"/home/alex/P3env/env/lib/python3.4/site-packages/pip/commands/install.py", 
line 283, in run
     requirement_set.install(install_options, global_options, 
root=options.root_path)
   File "/home/alex/P3env/env/lib/python3.4/site-packages/pip/req.py", 
line 1435, in install
     requirement.install(install_options, global_options, *args, 
**kwargs)
   File "/home/alex/P3env/env/lib/python3.4/site-packages/pip/req.py", 
line 706, in install
     cwd=self.source_dir, filter_stdout=self._filter_install, 
show_stdout=False)
   File "/home/alex/P3env/env/lib/python3.4/site-packages/pip/util.py", 
line 697, in call_subprocess
     % (command_desc, proc.returncode, cwd))
pip.exceptions.InstallationError: Command 
/home/alex/P3env/env/bin/python3 -c "import setuptools, 
tokenize;__file__='/home/alex/P3env/env/build/lxml/setup.py';exec(compile(getattr(tokenize, 
'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 
'exec'))" install --record /tmp/pip-56yiw_ye-record/install-record.txt 
--single-version-externally-managed --compile --install-headers 
/home/alex/P3env/env/include/site/python3.4 failed with error code 1 in 
/home/alex/P3env/env/build/lxml



From stefan_ml at behnel.de  Thu Apr  9 22:10:50 2015
From: stefan_ml at behnel.de (Stefan Behnel)
Date: Thu, 09 Apr 2015 22:10:50 +0200
Subject: [Tutor] pip install lxml fails
In-Reply-To: <957838078c7c686d7e635054e832eba5@sonic.net>
References: <e36efeaaa5940120829fba845dcd9dd5@sonic.net>
 <20150409140818.GB6451@test-chamber-1.castopulence.org>
 <aa9fe9337423a4d0411239370c226758@sonic.net> <mg68be$7bd$1@ger.gmane.org>
 <957838078c7c686d7e635054e832eba5@sonic.net>
Message-ID: <mg6mcb$4v0$1@ger.gmane.org>

Alex Kleider schrieb am 09.04.2015 um 21:49:
> On 2015-04-09 09:11, Stefan Behnel wrote:
>> All you need to do is install the "-dev" package that goes with your Python
>> installation, e.g. "python3-dev" should match Python 3.4 in current Ubuntu
>> releases.
>>
>> The reason why it's in a separate package is that many people actually
>> don't need this, e.g. when they only install plain Python packages or use
>> the Ubuntu provided binary packages that they can install via apt (e.g.
>> "sudo apt-get install python-lxml").
> 
> Thanks Brandon and Sefan.  It proved correct that I did not have
> python3-dev installed
> .. but after intalling it, the pip install lxml still fails!
> 
> There's a huge amount of output but what follows might provide clues as to
> the current problem:
> [...]
> /usr/bin/ld: cannot find -lz

Same thing, you need to make zlib available to the build. Ubuntu calls the
package "zlib1g-dev". And while you're at it, make sure you also have
"libxml2-dev" and "libxslt-dev".

The official installation instructions can be found here, BTW:

http://lxml.de/installation.html

Stefan



From __peter__ at web.de  Thu Apr  9 22:26:46 2015
From: __peter__ at web.de (Peter Otten)
Date: Thu, 09 Apr 2015 22:26:46 +0200
Subject: [Tutor] pip install lxml fails
References: <e36efeaaa5940120829fba845dcd9dd5@sonic.net>
 <20150409140818.GB6451@test-chamber-1.castopulence.org>
 <aa9fe9337423a4d0411239370c226758@sonic.net> <mg68be$7bd$1@ger.gmane.org>
 <957838078c7c686d7e635054e832eba5@sonic.net> <mg6mcb$4v0$1@ger.gmane.org>
Message-ID: <mg6na8$l5t$1@ger.gmane.org>

Stefan Behnel wrote:

> Alex Kleider schrieb am 09.04.2015 um 21:49:
>> On 2015-04-09 09:11, Stefan Behnel wrote:
>>> All you need to do is install the "-dev" package that goes with your
>>> Python installation, e.g. "python3-dev" should match Python 3.4 in
>>> current Ubuntu releases.
>>>
>>> The reason why it's in a separate package is that many people actually
>>> don't need this, e.g. when they only install plain Python packages or
>>> use the Ubuntu provided binary packages that they can install via apt
>>> (e.g. "sudo apt-get install python-lxml").
>> 
>> Thanks Brandon and Sefan.  It proved correct that I did not have
>> python3-dev installed
>> .. but after intalling it, the pip install lxml still fails!
>> 
>> There's a huge amount of output but what follows might provide clues as
>> to the current problem:
>> [...]
>> /usr/bin/ld: cannot find -lz
> 
> Same thing, you need to make zlib available to the build. Ubuntu calls the
> package "zlib1g-dev". And while you're at it, make sure you also have
> "libxml2-dev" and "libxslt-dev".
> 
> The official installation instructions can be found here, BTW:
> 
> http://lxml.de/installation.html

I'd try

$ sudo apt-get build-dep python3-lxml

This should install all build dependencies of the python3-lxml package which 
are likely the same as those of a manual installation of lxml.


From akleider at sonic.net  Thu Apr  9 22:27:37 2015
From: akleider at sonic.net (Alex Kleider)
Date: Thu, 09 Apr 2015 13:27:37 -0700
Subject: [Tutor] pip install lxml fails
In-Reply-To: <957838078c7c686d7e635054e832eba5@sonic.net>
References: <e36efeaaa5940120829fba845dcd9dd5@sonic.net>
 <20150409140818.GB6451@test-chamber-1.castopulence.org>
 <aa9fe9337423a4d0411239370c226758@sonic.net> <mg68be$7bd$1@ger.gmane.org>
 <957838078c7c686d7e635054e832eba5@sonic.net>
Message-ID: <a16e069da2e9f4fc8c09a87d69c192ff@sonic.net>

I tried something different and although not successful, there seems to 
be some progress:

----------------------------------------
(env)alex at t61p:~/P3env$ CFLAGS="-O0" STATIC_DEPS=true pip install lxml

.....
Exception: Command "make -j3" returned code 512

----------------------------------------
Cleaning up...
Command python setup.py egg_info failed with error code 1 in 
/home/alex/P3env/env/build/lxml
Storing debug log for failure in /home/alex/.pip/pip.log

The part of .pip/pip.log that might prove useful is as follows:

     make[1]: Leaving directory 
`/home/alex/P3env/env/build/lxml/build/tmp/libiconv-1.14/srclib'
     make: *** [all] Error 2
     Building lxml version 3.4.2.
     Latest version of libiconv is 1.14
     Downloading libiconv into libs/libiconv-1.14.tar.gz
     Unpacking libiconv-1.14.tar.gz into build/tmp
     Latest version of libxml2 is 2.9.2
     Downloading libxml2 into libs/libxml2-2.9.2.tar.gz
     Unpacking libxml2-2.9.2.tar.gz into build/tmp
     Latest version of libxslt is 1.1.28
     Downloading libxslt into libs/libxslt-1.1.28.tar.gz
     Unpacking libxslt-1.1.28.tar.gz into build/tmp
     Starting build in build/tmp/libiconv-1.14
     Traceback (most recent call last):
       File "<string>", line 17, in <module>
       File "/home/alex/P3env/env/build/lxml/setup.py", line 230, in 
<module>
         **setup_extra_options()
       File "/home/alex/P3env/env/build/lxml/setup.py", line 144, in 
setup_extra_options
         STATIC_CFLAGS, STATIC_BINARIES)
       File "/home/alex/P3env/env/build/lxml/setupinfo.py", line 57, in 
ext_modules
         multicore=OPTION_MULTICORE)
       File "/home/alex/P3env/env/build/lxml/buildlibxml.py", line 348, 
in build_libxml2xslt
         cmmi(configure_cmd, libiconv_dir, multicore, **call_setup)
       File "/home/alex/P3env/env/build/lxml/buildlibxml.py", line 285, 
in cmmi
         cwd=build_dir, **call_setup)
       File "/home/alex/P3env/env/build/lxml/buildlibxml.py", line 268, 
in call_subprocess
         raise Exception('Command "%s" returned code %s' % (cmd_desc, 
returncode))
     Exception: Command "make -j3" returned code 512
     Complete output from command python setup.py egg_info:
     checking for a BSD-compatible install... /usr/bin/install -c

checking whether build environment is sane... yes

....


From akleider at sonic.net  Thu Apr  9 22:40:57 2015
From: akleider at sonic.net (Alex Kleider)
Date: Thu, 09 Apr 2015 13:40:57 -0700
Subject: [Tutor] pip install lxml fails
In-Reply-To: <mg6na8$l5t$1@ger.gmane.org>
References: <e36efeaaa5940120829fba845dcd9dd5@sonic.net>
 <20150409140818.GB6451@test-chamber-1.castopulence.org>
 <aa9fe9337423a4d0411239370c226758@sonic.net> <mg68be$7bd$1@ger.gmane.org>
 <957838078c7c686d7e635054e832eba5@sonic.net> <mg6mcb$4v0$1@ger.gmane.org>
 <mg6na8$l5t$1@ger.gmane.org>
Message-ID: <c06463532aec22dfb94f080f11bc1d9f@sonic.net>

On 2015-04-09 13:26, Peter Otten wrote:

> I'd try
> 
> $ sudo apt-get build-dep python3-lxml

build-dep is not an apt-get command I've seen before but it did the 
trick!

> 
> This should install all build dependencies of the python3-lxml package 
> which
> are likely the same as those of a manual installation of lxml.

I can now
import lxml

Thank you very much, indeed!

Alex


From cybervigilante at gmail.com  Thu Apr  9 21:02:22 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Thu, 9 Apr 2015 12:02:22 -0700
Subject: [Tutor] annoying directory structure
Message-ID: <CALRAYNWHSYvd5N2X14EZpPdLntxyfj_RVPZTy0nEdzff+mkWiA@mail.gmail.com>

"The safest method would probably be to do `pip freeze > requirements.txt`,
copy the requirements.txt file to the new machine, and run `pip install -r
requirements.txt" --Zach

I looked at pip3 help (windows) and don't see  a -r command. However, it
does work. How do I get the "invisible" commands ;')

Another question. I have a set of training vids. Unfortunately, each vid is
in a subdir inside a subdir inside a subdir inside a subdir inside the
directory. Going down, down, down, up, up, up to nab them (they're short)
and remember where I am, is annoying. How do I use python to get a simple
straight list of the vids in directory order - full windows path - so I can
just copy and plug the paths into windows explorer, one at a time?

-- 
Jim

Guido van Rossum fan club and coffee bar looking for baristas who know
Python

From zachary.ware+pytut at gmail.com  Thu Apr  9 23:01:00 2015
From: zachary.ware+pytut at gmail.com (Zachary Ware)
Date: Thu, 9 Apr 2015 16:01:00 -0500
Subject: [Tutor] annoying directory structure
In-Reply-To: <CALRAYNWHSYvd5N2X14EZpPdLntxyfj_RVPZTy0nEdzff+mkWiA@mail.gmail.com>
References: <CALRAYNWHSYvd5N2X14EZpPdLntxyfj_RVPZTy0nEdzff+mkWiA@mail.gmail.com>
Message-ID: <CAKJDb-MztSOcUXJ8wr-fyDa9m+M=PEvpRBcms1TCydJMT1dvzA@mail.gmail.com>

On Thu, Apr 9, 2015 at 2:02 PM, Jim Mooney <cybervigilante at gmail.com> wrote:
> "The safest method would probably be to do `pip freeze > requirements.txt`,
> copy the requirements.txt file to the new machine, and run `pip install -r
> requirements.txt" --Zach
>
> I looked at pip3 help (windows) and don't see  a -r command. However, it
> does work. How do I get the "invisible" commands ;')

Try `pip3 help install` :)

> Another question. I have a set of training vids. Unfortunately, each vid is
> in a subdir inside a subdir inside a subdir inside a subdir inside the
> directory. Going down, down, down, up, up, up to nab them (they're short)
> and remember where I am, is annoying. How do I use python to get a simple
> straight list of the vids in directory order - full windows path - so I can
> just copy and plug the paths into windows explorer, one at a time?

Have a look at os.walk(), it will enable you to walk (hence the name)
through all directories in a tree.  Take a crack at it, and if you
have trouble come back with some code for us to look at.  You may also
need os.path.abspath to get the full path.

--
Zach

From cybervigilante at gmail.com  Fri Apr 10 00:17:51 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Thu, 9 Apr 2015 15:17:51 -0700
Subject: [Tutor] annoying directory structure
In-Reply-To: <CAKJDb-MztSOcUXJ8wr-fyDa9m+M=PEvpRBcms1TCydJMT1dvzA@mail.gmail.com>
References: <CALRAYNWHSYvd5N2X14EZpPdLntxyfj_RVPZTy0nEdzff+mkWiA@mail.gmail.com>
 <CAKJDb-MztSOcUXJ8wr-fyDa9m+M=PEvpRBcms1TCydJMT1dvzA@mail.gmail.com>
Message-ID: <CALRAYNV1j+_yGv25=q2ahCSZBdqykOLYrnfhaz9sC46Je5Qc=g@mail.gmail.com>

Looks like I can work it, but some walk paths are coming out as two strings
back to back, which I know python concatenates with print, but how do I
concatenate them without print so I can use them in my script to append to
the mp4 filenames and have a windows readable path?. i.e., I am getting
this sort of triplet when I go through the generator. After doing that the
rest seems easy enough:

A = ('I:\\VIDS\\Learn Python Track\\07. Regular Expressions in
Python\\Stage '
 '1\\01. Introduction to Regular Expressions\\07. Compiling and Loops',
 [],
 ['Compiling and Loops.mp4', 'Compiling and Loops.srt'])

>> A[0]

('I:\\VIDS\\Learn Python Track\\07. Regular Expressions in Python\\Stage '
 '1\\01. Introduction to Regular Expressions\\07. Compiling and Loops')

Still two unconcatenated strings

And why do I still have tuple parentheses for A[0], which should be a
concatenated string?


> > Another question. I have a set of training vids. Unfortunately, each vid
> is
> > in a subdir inside a subdir inside a subdir inside a subdir inside the
> > directory. Going down, down, down, up, up, up to nab them (they're short)
> > and remember where I am, is annoying. How do I use python to get a simple
> > straight list of the vids in directory order - full windows path - so I
> can
> > just copy and plug the paths into windows explorer, one at a time?
>
> Have a look at os.walk(), it will enable you to walk (hence the name)
> through all directories in a tree.  Take a crack at it, and if you
> have trouble come back with some code for us to look at.  You may also
> need os.path.abspath to get the full path.
>
> --
> Zach
>



-- 
Jim

"Stop, Harold! That bagel has radishes!"
"Thank God, Mary - you've saved me again!"

From zachary.ware+pytut at gmail.com  Fri Apr 10 01:31:49 2015
From: zachary.ware+pytut at gmail.com (Zachary Ware)
Date: Thu, 9 Apr 2015 18:31:49 -0500
Subject: [Tutor] annoying directory structure
In-Reply-To: <CALRAYNV1j+_yGv25=q2ahCSZBdqykOLYrnfhaz9sC46Je5Qc=g@mail.gmail.com>
References: <CALRAYNWHSYvd5N2X14EZpPdLntxyfj_RVPZTy0nEdzff+mkWiA@mail.gmail.com>
 <CAKJDb-MztSOcUXJ8wr-fyDa9m+M=PEvpRBcms1TCydJMT1dvzA@mail.gmail.com>
 <CALRAYNV1j+_yGv25=q2ahCSZBdqykOLYrnfhaz9sC46Je5Qc=g@mail.gmail.com>
Message-ID: <CAKJDb-O7PUWTNGQ=Cu8Rsc3Xg+CzxFc+784-AfLUnR9SWoA_fw@mail.gmail.com>

(Please use a bottom-posting/interleaved style of reply on this list,
it makes conversations much easier to follow.  I've fixed your message
in my response below.)

On Thu, Apr 9, 2015 at 5:17 PM, Jim Mooney <cybervigilante at gmail.com> wrote:
>> > Another question. I have a set of training vids. Unfortunately, each vid
>> is
>> > in a subdir inside a subdir inside a subdir inside a subdir inside the
>> > directory. Going down, down, down, up, up, up to nab them (they're short)
>> > and remember where I am, is annoying. How do I use python to get a simple
>> > straight list of the vids in directory order - full windows path - so I
>> can
>> > just copy and plug the paths into windows explorer, one at a time?
>>
>> Have a look at os.walk(), it will enable you to walk (hence the name)
>> through all directories in a tree.  Take a crack at it, and if you
>> have trouble come back with some code for us to look at.  You may also
>> need os.path.abspath to get the full path.
>
> Looks like I can work it, but some walk paths are coming out as two strings
> back to back, which I know python concatenates with print, but how do I
> concatenate them without print so I can use them in my script to append to
> the mp4 filenames and have a windows readable path?. i.e., I am getting
> this sort of triplet when I go through the generator. After doing that the
> rest seems easy enough:
>
> A = ('I:\\VIDS\\Learn Python Track\\07. Regular Expressions in
> Python\\Stage '
>  '1\\01. Introduction to Regular Expressions\\07. Compiling and Loops',
>  [],
>  ['Compiling and Loops.mp4', 'Compiling and Loops.srt'])
>
>>> A[0]
>
> ('I:\\VIDS\\Learn Python Track\\07. Regular Expressions in Python\\Stage '
>  '1\\01. Introduction to Regular Expressions\\07. Compiling and Loops')
>
> Still two unconcatenated strings
>
> And why do I still have tuple parentheses for A[0], which should be a
> concatenated string?

I'll need to see some actual code (namely, where and how you used
os.walk) to have any real idea of what's going on. The online docs for
os.walk have a pretty good explanation and example.

-- 
Zach

From davea at davea.name  Fri Apr 10 01:44:27 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 09 Apr 2015 19:44:27 -0400
Subject: [Tutor] annoying directory structure
In-Reply-To: <CALRAYNV1j+_yGv25=q2ahCSZBdqykOLYrnfhaz9sC46Je5Qc=g@mail.gmail.com>
References: <CALRAYNWHSYvd5N2X14EZpPdLntxyfj_RVPZTy0nEdzff+mkWiA@mail.gmail.com>
 <CAKJDb-MztSOcUXJ8wr-fyDa9m+M=PEvpRBcms1TCydJMT1dvzA@mail.gmail.com>
 <CALRAYNV1j+_yGv25=q2ahCSZBdqykOLYrnfhaz9sC46Je5Qc=g@mail.gmail.com>
Message-ID: <55270EDB.2070903@davea.name>

On 04/09/2015 06:17 PM, Jim Mooney wrote:

Please put your remarks *after* whatever quoting you do, not before.  In 
other words, don't top-post.

> Looks like I can work it, but some walk paths are coming out as two strings
> back to back, which I know python concatenates with print, but how do I
> concatenate them without print so I can use them in my script to append to
> the mp4 filenames and have a windows readable path?. i.e., I am getting
> this sort of triplet when I go through the generator. After doing that the
> rest seems easy enough:
>
> A = ('I:\\VIDS\\Learn Python Track\\07. Regular Expressions in
> Python\\Stage '
>   '1\\01. Introduction to Regular Expressions\\07. Compiling and Loops',
>   [],
>   ['Compiling and Loops.mp4', 'Compiling and Loops.srt'])
>
>>> A[0]
>
> ('I:\\VIDS\\Learn Python Track\\07. Regular Expressions in Python\\Stage '
>   '1\\01. Introduction to Regular Expressions\\07. Compiling and Loops')

that's not what you'd get if you had done the previous two lines.  So 
please post some real code, and maybe you'll get some help.

>
> Still two unconcatenated strings

You didn't do anything to concatenate anything, so I'm not sure what 
you're talking about.

>
> And why do I still have tuple parentheses for A[0], which should be a
> concatenated string?
>

Nonsense without context.  What's your code?

If you're inside a loop on os.walk, the easiest way to make readable 
code is to use implicit tuple unpacking.

See https://docs.python.org/3.4/library/os.html#os.walk

for dirpath, dirnames, filenames = os.walk(  whatever ):
     #Do something here with dirpath and each of the filenames

Once you have a path and a basename you need to combine, you *could* use 
+ on the two strings.  But it'd be much better to use os.path.join().  See

https://docs.python.org/3/library/os.path.html#os.path.join




-- 
DaveA

From akleider at sonic.net  Fri Apr 10 02:42:19 2015
From: akleider at sonic.net (Alex Kleider)
Date: Thu, 09 Apr 2015 17:42:19 -0700
Subject: [Tutor] annoying directory structure
In-Reply-To: <55270EDB.2070903@davea.name>
References: <CALRAYNWHSYvd5N2X14EZpPdLntxyfj_RVPZTy0nEdzff+mkWiA@mail.gmail.com>
 <CAKJDb-MztSOcUXJ8wr-fyDa9m+M=PEvpRBcms1TCydJMT1dvzA@mail.gmail.com>
 <CALRAYNV1j+_yGv25=q2ahCSZBdqykOLYrnfhaz9sC46Je5Qc=g@mail.gmail.com>
 <55270EDB.2070903@davea.name>
Message-ID: <fa11ee61231df22dbf647ab81ee9769c@sonic.net>

On 2015-04-09 16:44, Dave Angel wrote:


> for dirpath, dirnames, filenames = os.walk(  whatever ):

I've always seen it written
>>> for dirpath, dirnames, filenames in os.walk(  whatever ):

Comments??

From zachary.ware+pytut at gmail.com  Fri Apr 10 02:45:10 2015
From: zachary.ware+pytut at gmail.com (Zachary Ware)
Date: Thu, 9 Apr 2015 19:45:10 -0500
Subject: [Tutor] annoying directory structure
In-Reply-To: <fa11ee61231df22dbf647ab81ee9769c@sonic.net>
References: <CALRAYNWHSYvd5N2X14EZpPdLntxyfj_RVPZTy0nEdzff+mkWiA@mail.gmail.com>
 <CAKJDb-MztSOcUXJ8wr-fyDa9m+M=PEvpRBcms1TCydJMT1dvzA@mail.gmail.com>
 <CALRAYNV1j+_yGv25=q2ahCSZBdqykOLYrnfhaz9sC46Je5Qc=g@mail.gmail.com>
 <55270EDB.2070903@davea.name> <fa11ee61231df22dbf647ab81ee9769c@sonic.net>
Message-ID: <CAKJDb-Pg2U=whX1yek5Kg3ctpGHHYsxq+pX3scDcw41qvK8vWg@mail.gmail.com>

On Thu, Apr 9, 2015 at 7:42 PM, Alex Kleider <akleider at sonic.net> wrote:
> On 2015-04-09 16:44, Dave Angel wrote:
>
>
>> for dirpath, dirnames, filenames = os.walk(  whatever ):
>
>
> I've always seen it written
>>>>
>>>> for dirpath, dirnames, filenames in os.walk(  whatever ):
>
>
> Comments??

Typo on Dave's part, I'm quite certain he meant to use 'in', since '='
there is a SyntaxError.

-- 
Zach

From davea at davea.name  Fri Apr 10 03:48:25 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 09 Apr 2015 21:48:25 -0400
Subject: [Tutor] annoying directory structure
In-Reply-To: <CAKJDb-Pg2U=whX1yek5Kg3ctpGHHYsxq+pX3scDcw41qvK8vWg@mail.gmail.com>
References: <CALRAYNWHSYvd5N2X14EZpPdLntxyfj_RVPZTy0nEdzff+mkWiA@mail.gmail.com>
 <CAKJDb-MztSOcUXJ8wr-fyDa9m+M=PEvpRBcms1TCydJMT1dvzA@mail.gmail.com>
 <CALRAYNV1j+_yGv25=q2ahCSZBdqykOLYrnfhaz9sC46Je5Qc=g@mail.gmail.com>
 <55270EDB.2070903@davea.name> <fa11ee61231df22dbf647ab81ee9769c@sonic.net>
 <CAKJDb-Pg2U=whX1yek5Kg3ctpGHHYsxq+pX3scDcw41qvK8vWg@mail.gmail.com>
Message-ID: <55272BE9.1030500@davea.name>

On 04/09/2015 08:45 PM, Zachary Ware wrote:
> On Thu, Apr 9, 2015 at 7:42 PM, Alex Kleider <akleider at sonic.net> wrote:
>> On 2015-04-09 16:44, Dave Angel wrote:
>>
>>
>>> for dirpath, dirnames, filenames = os.walk(  whatever ):
>>
>>
>> I've always seen it written
>>>>>
>>>>> for dirpath, dirnames, filenames in os.walk(  whatever ):
>>
>>
>> Comments??
>
> Typo on Dave's part, I'm quite certain he meant to use 'in', since '='
> there is a SyntaxError.
>

Quite right.  I should have copy/pasted it from the first example 
following the os.walk tag on the webpage I showed.  In fact, I think I 
did paste the first 3 tokens from the tuple description earlier on that 
link, and trusted my fingers to do the rest.

Sorry for the typo, but not for the advice.

-- 
DaveA

From cybervigilante at gmail.com  Fri Apr 10 05:07:33 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Thu, 9 Apr 2015 20:07:33 -0700
Subject: [Tutor] Tutor Digest, Vol 134,
 Issue 27 - Re: annoying directory structure (Zachary Ware)
Message-ID: <CALRAYNULQpO5oU=p+Vf0Pnd67LKJRkNPcx98u63TS-s2k344yA@mail.gmail.com>

>
> I'll need to see some actual code (namely, where and how you used
> os.walk) to have any real idea of what's going on. The online docs for
> os.walk have a pretty good explanation and example.


Zach

This worked. I didn't know why I got doubled strings, but print
concatenated them so I printed to a file, and the text lines all open an
mp4 in windows explorer, as expected. Unfortunately they aren't in order,
so I guess I'll have to actually read up on walk. I just wanted to knock it
out quickly by figuring out the walk output format, and get on with the
course ;')

tutfiles = open('tutfiles.txt', 'w')
p = os.walk('I:\\VIDS\\Learn Python Track\\')
for triplet in p:
    if triplet[2] == []:
        continue
    else:
        if 'mp4' in triplet[2][0]:
            print(triplet[0] + '\\' + triplet[2][0], file=tutfiles)

tutfiles.close()

Here are the out of order textlines, going from Track\08 to Track\01

I:\VIDS\Learn Python Track\08. Using Databases in Python\Stage 1\01. Meet
Peewee\01. Meet Peewee, Our ORM\Meet Peewee, Our ORM.mp4
I:\VIDS\Learn Python Track\01. Python Basics\Python Basics\Stage 6\06.
Pick a Number! Any Number!\02. The Solution\The Solution.mp4

Here is what I meant by doubled strings. The tuples output by walk had two
strings in a row as element zero, Prior to the first comma, with element 1
being an empty list, so I couldn't figure how to concatenate the two
strings directly, without print, to use in my file listing.

(*'I:\\VIDS\\Learn Python Track\\07. Regular Expressions in Python\\Stage '
'1\\01. Introduction to Regular Expressions\\07. Compiling and Loops'*, [],
['Compiling and Loops.mp4', 'Compiling and Loops.srt'])

Jim

From kale at kalegood.com  Fri Apr 10 02:39:11 2015
From: kale at kalegood.com (Kale Good)
Date: Thu, 09 Apr 2015 20:39:11 -0400
Subject: [Tutor] Execute on 200 line segments of CSV
Message-ID: <55271BAF.3080105@kalegood.com>

Hello,
Python newbie here; I'm trying to figure out how to get python to 
execute code on 200-line chunks of a 5000 line CSV. I haven't a clue 
where to start on this. So the code would execute on lines 1-200, 
201-400, etc.

Thanks,
Kale

-- 
------------------------------------------------------------------------
Kale Good: Guitar Instructor ?
phillyguitarlessons.com <http://phillyguitarlessons.com>
phone: (215)260-5383

  * 4705 Baltimore Ave, Phila, PA 19143 :Mailing & Lessons
  * 1867 Frankford Ave. Phila, PA 19125 :Lessons

Google+ <https://plus.google.com/b/105422331794047992190/>
Facebook <http://facebook.com/KaleGoodGuitarStudio>
Read my article "The Seven Secrets to Six String Success 
<http://www.guitarnoise.com/lesson/seven-secrets-to-six-string-success/>" at 
GuitarNoise.com <http://guitarnoise.com>
Leading the Journey from No-Skills-Guitarist to Talented Musician!


From __peter__ at web.de  Fri Apr 10 09:57:25 2015
From: __peter__ at web.de (Peter Otten)
Date: Fri, 10 Apr 2015 09:57:25 +0200
Subject: [Tutor] Execute on 200 line segments of CSV
References: <55271BAF.3080105@kalegood.com>
Message-ID: <mg7vp6$heb$1@ger.gmane.org>

Kale Good wrote:

> Python newbie here; I'm trying to figure out how to get python to
> execute code on 200-line chunks of a 5000 line CSV. I haven't a clue
> where to start on this. So the code would execute on lines 1-200,
> 201-400, etc.

Use the csv module 

https://docs.python.org/3.4/library/csv.html

to read the rows from the CSV.

Iterate over the rows with a for loop and collect the rows in a list (let's 
call it 'chunk').
Check the chunk list's length on every iteration of the for loop. When the 
list's length is 200 do what you want with those 200 rows, then replace the 
list with a new empty list.

When the for loop ends there may be lines remaining in the chunk list, e. g. 
when the CSV file has 5100 lines there will be a final chunk containing 100 
rows that is not handled by the code in the for loop. It's up you to detect 
it and to decide what to do with this smaller chunk.

Come back when you have some code that we can help fix or improve.


From davea at davea.name  Fri Apr 10 13:39:44 2015
From: davea at davea.name (Dave Angel)
Date: Fri, 10 Apr 2015 07:39:44 -0400
Subject: [Tutor] Tutor Digest, Vol 134,
 Issue 27 - Re: annoying directory structure (Zachary Ware)
In-Reply-To: <CALRAYNULQpO5oU=p+Vf0Pnd67LKJRkNPcx98u63TS-s2k344yA@mail.gmail.com>
References: <CALRAYNULQpO5oU=p+Vf0Pnd67LKJRkNPcx98u63TS-s2k344yA@mail.gmail.com>
Message-ID: <5527B680.5090604@davea.name>

Please at least fix the subject line.  Thanks for deleting the 
irrelevant parts of the digest, but you're pretending to continue a 
thread, while having a bogus subject, and sending a message that's not 
at all linked to the previous part of the thread.

When I used to use a digest, I was able to open a particular message 
within the digest (I think the individual messages were considered 
attachments, and I just double-clicked on one such attachment).  Then i 
could reply, and it actually worked.  Your mileage may vary, which is 
why it's better to just skip digests when you're actually participating.


On 04/09/2015 11:07 PM, Jim Mooney wrote:
>>
>> I'll need to see some actual code (namely, where and how you used
>> os.walk) to have any real idea of what's going on. The online docs for
>> os.walk have a pretty good explanation and example.
>
>
> Zach
>
> This worked. I didn't know why I got doubled strings, but print
> concatenated them so I printed to a file, and the text lines all open an
> mp4 in windows explorer, as expected. Unfortunately they aren't in order,
> so I guess I'll have to actually read up on walk. I just wanted to knock it
> out quickly by figuring out the walk output format, and get on with the
> course ;')
>
> tutfiles = open('tutfiles.txt', 'w')
> p = os.walk('I:\\VIDS\\Learn Python Track\\')
> for triplet in p:
>      if triplet[2] == []:
>          continue
>      else:
>          if 'mp4' in triplet[2][0]:

If you're looking for an extension of mp4, you should either use 
endswith, or use os.path.splitext to get the actual extension.  The way 
you have it now, you'll also tag a file that happens to have those 3 
letters somewhere in the middle.

The other thing weird in this code is you're only looking at the first 
file in the directory.  If the file you're interested in happens to be 
the fifth, you'll never see it.  Normally, you need to loop over triplet[2]



>              print(triplet[0] + '\\' + triplet[2][0], file=tutfiles)
>
> tutfiles.close()
>
> Here are the out of order textlines, going from Track\08 to Track\01

If you want the directory names to be sorted, and your OS doesn't happen 
to sort them, you must do it yourself.  Simply sort triplet[1] each 
time.  If you also want the filenames within a directory to be sorted, 
then sort them as well.  These two sorts would take place just before 
your "if triple3t[2]" above.

>
> I:\VIDS\Learn Python Track\08. Using Databases in Python\Stage 1\01. Meet
> Peewee\01. Meet Peewee, Our ORM\Meet Peewee, Our ORM.mp4
> I:\VIDS\Learn Python Track\01. Python Basics\Python Basics\Stage 6\06.
> Pick a Number! Any Number!\02. The Solution\The Solution.mp4
>
> Here is what I meant by doubled strings. The tuples output by walk had two
> strings in a row as element zero, Prior to the first comma, with element 1
> being an empty list, so I couldn't figure how to concatenate the two
> strings directly, without print, to use in my file listing.

No idea what this paragraph is trying to say.  But the first element of 
the tuple is a string, so it cannot have two items in it.  If it seems 
to, perhaps you have some unusual filenames, like the asterisk and 
parenthesis in the following thingie.

>
> (*'I:\\VIDS\\Learn Python Track\\07. Regular Expressions in Python\\Stage '
> '1\\01. Introduction to Regular Expressions\\07. Compiling and Loops'*, [],
> ['Compiling and Loops.mp4', 'Compiling and Loops.srt'])
>

If we're going to make any sense of that mess, you need to show the code 
that produced it.

-- 
DaveA

From dyoo at hashcollision.org  Fri Apr 10 20:46:32 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 10 Apr 2015 11:46:32 -0700
Subject: [Tutor] Execute on 200 line segments of CSV
In-Reply-To: <mg7vp6$heb$1@ger.gmane.org>
References: <55271BAF.3080105@kalegood.com> <mg7vp6$heb$1@ger.gmane.org>
Message-ID: <CAGZAPF77OqTCgkwxcdGtmGs79hr_1TsJcNSxiT7ExgmyrxrK0w@mail.gmail.com>

>> Python newbie here; I'm trying to figure out how to get python to
>> execute code on 200-line chunks of a 5000 line CSV. I haven't a clue
>> where to start on this. So the code would execute on lines 1-200,
>> 201-400, etc.


Peter's suggestion to reuse the csv library is appropriate: you want
to reuse the csv parser that's available in the standard library.
This will give you an "iterable", an object that we can use to march
down each row of the file, using the technique that Peter describes.

---

The following is for intermediate programmers.  The "chunking" logic
can be split off from the processing of those chunks, if we take
advantage of Python's generators.  Something like this:

##################################
def chunk(iterable, chunkSize):
    """Takes an iterable, and "chunks" it into blocks."""
    currentChunk = []
    for item in iterable:
        currentChunk.append(item)
        if len(currentChunk) >= chunkSize:
            yield(currentChunk)
            currentChunk = []
    if len(currentChunk) > 0:
        yield(currentChunk)
##################################


If we have a utility like this, then we can write a natural loop on
the chunks, such as:

###################################################################
>>> blocks = chunk('thisisatestoftheemergencybroadcastsystem', 5)
>>> for b in blocks:
...     print b
...
['t', 'h', 'i', 's', 'i']
['s', 'a', 't', 'e', 's']
['t', 'o', 'f', 't', 'h']
['e', 'e', 'm', 'e', 'r']
['g', 'e', 'n', 'c', 'y']
['b', 'r', 'o', 'a', 'd']
['c', 'a', 's', 't', 's']
['y', 's', 't', 'e', 'm']
###################################################################

Splitting of the chunking logic like this should allow us to separate
one concern, the chunking, from the primary concern, the processing of
each chunk.

From zachary.ware+pytut at gmail.com  Sat Apr 11 02:14:16 2015
From: zachary.ware+pytut at gmail.com (Zachary Ware)
Date: Fri, 10 Apr 2015 19:14:16 -0500
Subject: [Tutor] annoying directory structure
Message-ID: <CAKJDb-OAbZMEY7+fHM8+2FFXe-VqF3V5PCbu=EyEBGahtBbaNQ@mail.gmail.com>

On Thu, Apr 9, 2015 at 10:07 PM, Jim Mooney <cybervigilante at gmail.com> wrote:
[Previously, I wrote:]
>> I'll need to see some actual code (namely, where and how you used
>> os.walk) to have any real idea of what's going on. The online docs for
>> os.walk have a pretty good explanation and example.
>
>
> This worked. I didn't know why I got doubled strings, but print
> concatenated them so I printed to a file, and the text lines all open an
> mp4 in windows explorer, as expected. Unfortunately they aren't in order,
> so I guess I'll have to actually read up on walk. I just wanted to knock it
> out quickly by figuring out the walk output format, and get on with the
> course ;')
>
> tutfiles = open('tutfiles.txt', 'w')
> p = os.walk('I:\\VIDS\\Learn Python Track\\')
> for triplet in p:
>     if triplet[2] == []:
>         continue
>     else:
>         if 'mp4' in triplet[2][0]:
>             print(triplet[0] + '\\' + triplet[2][0], file=tutfiles)
>
> tutfiles.close()

Frankly, that's a bit horrifying :).  I'm glad you came up with a
solution that works for you using the tools available to you, but it's
far from idiomatic Python code.

Here's how I would write it (please excuse any syntax errors; I'm not
testing it.  Logic errors, I'll take the blame :) ).

"""
import os

def get_filenames(top_level_dir):
    all_video_files = []
    for dir, dirs, files in os.walk(os.path.abspath(top_level_dir)):
        for filename in files:
            if filename.endswith('.mp4'):
                all_files.append(os.path.join(dir, filename))
    return all_video_files

print(*get_filenames("your root directory"), sep='\n')
"""

If you need them sorted in some particular way, you can sort the list
before printing it, using the sort() method of the list (and probably
the 'key' keyword argument).

Please take a look at this and try to understand what it's doing, and
ask about anything that doesn't make sense (that's the most important
part!).

Hope this helps,
-- 
Zach

From vick1975 at orange.mu  Sat Apr 11 14:32:38 2015
From: vick1975 at orange.mu (Vick)
Date: Sat, 11 Apr 2015 16:32:38 +0400
Subject: [Tutor] Hi
Message-ID: <000001d07453$997a48a0$cc6ed9e0$@orange.mu>

 

Hello

 

I've been using Python 27 on Windows for as long as I have used a computer
for intelligent purposes, viz. since 2000 I think, well the earlier versions
till the current version I'm using now. I used it primarily for mathematical
precision on numerical computations. I make my own codes. I'm fluent in it
and in VBA. I also use Mathematica (Home Edition) to compare. However as
Mathematica is largely symbolic, I prefer Python.

 

However I recently talked to a guy online and he told me the following,
which actually intrigued and surprised me:

 

"The vast majority of numerical codes in science, including positional
astronomy, are written in Fortran and C/C++.  If you wish to use these codes
in minority and less efficient languages such as Python and VBA, learning to
translate this code into those languages is a skill you will have to
acquire."

 

The "codes" in question are referring to a query I posed to him regarding
the GUST86 theory on the computational position of Uranus' natural
satellites authored by Laskar and Jacobson in 1987. The "code" is readily
downloadable in Fortran at the IMCCE ftp site.

 

But his statement is insinuating that Python is inferior to Fortran as a
mathematical tool and that all of the scientific community prefers to use
Fortran.

 

My question is simple: Is he right or wrong?

 

Thanks

Vick


From steve at pearwood.info  Sat Apr 11 15:41:13 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 11 Apr 2015 23:41:13 +1000
Subject: [Tutor] Hi
In-Reply-To: <000001d07453$997a48a0$cc6ed9e0$@orange.mu>
References: <000001d07453$997a48a0$cc6ed9e0$@orange.mu>
Message-ID: <20150411134112.GH5760@ando.pearwood.info>

Hi Vick, and welcome!

My replies to your questions are below, interleaved with your comments.

On Sat, Apr 11, 2015 at 04:32:38PM +0400, Vick wrote:

> However I recently talked to a guy online and he told me the following,
> which actually intrigued and surprised me:
> 
> "The vast majority of numerical codes in science, including positional
> astronomy, are written in Fortran and C/C++.  If you wish to use these codes
> in minority and less efficient languages such as Python and VBA, learning to
> translate this code into those languages is a skill you will have to
> acquire."
[...]
> But his statement is insinuating that Python is inferior to Fortran as a
> mathematical tool and that all of the scientific community prefers to use
> Fortran.
>
> My question is simple: Is he right or wrong?

He is partly right, partly wrong. But mostly wrong. Twenty years ago, if 
you wanted to do scientific computing, C and Fortran were essential. 
They are still very important, but they are no longer essential.

There are many professional-quality mathematical libraries. Older 
libraries are nearly all written in C/C++ or Fortran. Some are older 
libraries are written in Pascal, but because few people use Pascal any 
more, you won't find many of them still in use. Some newer libraries are 
written in Java. In the future, I would expect new scientific libraries 
to start coming out written in Julia:

http://julialang.org/

Although these libraries are written in C or Fortran, you don't need to 
program in those two languages to *use* those libraries. Most scripting 
languages like Python, Lua or Ruby include ways to call code in C or 
Fortran libraries as if they were written in Python (or Lua, Ruby, and 
so forth). We call languages like Python a "glue language", because it 
is very good for "gluing together" code from different libraries. You 
want to use this library for planetary orbit calculations, written in 
Fortran, and that library for calculating lunar eclipses written in C, 
so you use a Python script to bring them together.

Many mathematicians, statisticians and scientists use products such as 
Mathematica, Matlab, R, SAS, Minitab, Maple, and similar. These are all 
good products that have been around for a long time, with their own 
strengths and weaknesses.

One Python-based product which is becoming widely used in scientific 
circles is Numpy, together with its sister-library Scipy. The core 
numeric routines in Numpy and Scipy are mostly written in C and Fortran, 
but the interface is designed for use with Python.

http://www.numpy.org/
http://www.scipy.org/

Another Python product is SAGE, which aims to be a free alternative to 
Maple, Mathematica and other similar products.

http://www.sagemath.org/

The idea is to create a group of powerful maths, statistics and 
scientific libraries. Those libraries can use whatever language they 
want, and often they are written in C and Fortran, but the glue that 
holds them together is Python. Together, they combine the power of 
low-level, hard-to-use but powerful fast languages like Fortran and C 
with the ease of use and convenience of modern high-level languages like 
Python.

The core of scientific computing with Python includes:

Numpy - fast N-dimensional array calculations
Scipy - scientific computing libraries
Matplotlib - 2D graphing
IPython - enhanced interactive console with Mathematica-like notebook
Sympy - symbolic mathematics 
Pandas - data analysis
SAGE - integrated scientific computing system

Parts of these are written in Python, and parts in C, Fortran, 
Javascript, and potentially any language imaginable.

I also expect that people can start using PyPy to run pure-Python code 
almost as fast as C:

http://pypy.org/

Or they can use Cython to write C code using Python syntax:

http://cython.org/
?
All of these are parts of the Python ecosystem, and are why Python is 
currently becoming the "go-to" language for scientific computing. Where 
scientists used to write code in Fortran (hard and slow to write, but 
fast to run) or expensive proprietary products like Mathematica or 
Matlab, many people are gradually moving towards the Python ecosystem of 
Python, Numpy, IPython notebooks, and others.

This post explains Python's advantages over Matlab, why the author 
thinks that scientific computing will continue to move towards Python, 
and links to a number of other good articles from people who already 
have done so.

http://cyrille.rossant.net/why-using-python-for-scientific-computing/


My advice if you want to be a good scientific programmer:

- Stay with Python. Anyone who tries to tell you that you need to know 
  how to program in Fortran or C to do scientific computing is wrong.
- Learn how to program in Python as well as possible.
- Learn when *not* to program in Python, and know when to use existing 
  tools already written in C, Fortran or other languages. Chances are
  very good that Numpy, Scipy and others above already solve some of 
  your problems.
- If you really need high-speed computing power that Python alone 
  cannot provide, consider PyPy, Cython or Numba first. If and only if 
  they still don't provide what you need should you bother learning
  C or Fortran and using those.




-- 
Steve

From wrw at mac.com  Sat Apr 11 15:39:43 2015
From: wrw at mac.com (William Ray Wing)
Date: Sat, 11 Apr 2015 09:39:43 -0400
Subject: [Tutor] Hi
In-Reply-To: <000001d07453$997a48a0$cc6ed9e0$@orange.mu>
References: <000001d07453$997a48a0$cc6ed9e0$@orange.mu>
Message-ID: <FCAD6842-22A1-4736-91B6-4102AA8D88DC@mac.com>


> On Apr 11, 2015, at 8:32 AM, Vick <vick1975 at orange.mu> wrote:
> 

[byte]

> However I recently talked to a guy online and he told me the following,
> which actually intrigued and surprised me:
> 
> "The vast majority of numerical codes in science, including positional
> astronomy, are written in Fortran and C/C++.  If you wish to use these codes
> in minority and less efficient languages such as Python and VBA, learning to
> translate this code into those languages is a skill you will have to
> acquire."
> 
> The "codes" in question are referring to a query I posed to him regarding
> the GUST86 theory on the computational position of Uranus' natural
> satellites authored by Laskar and Jacobson in 1987. The "code" is readily
> downloadable in Fortran at the IMCCE ftp site.
> 
> But his statement is insinuating that Python is inferior to Fortran as a
> mathematical tool and that all of the scientific community prefers to use
> Fortran.
> 
> My question is simple: Is he right or wrong?
> 
> 

He is probably right, but only because most large scientific codes have historical roots that date back to the days when FORTRAN was the only language readily available on the computers scientists used.  Even today, FORTRAN compilers can frequently optimize typical scientific code to tighter (faster) executable code than the compilers for other, more modern, richer languages.  HOWEVER, that said, more and more scientific code is being written with Python as the organizing language which calls mathematical libraries written in FORTRAN.  Libraries like numpy make heavy use of FORTRAN arrays, while allowing the scientific programmer to concentrate on the higher levels of the science being modeled.

Bill

> 
> Thanks
> 
> Vick
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor


From martin at linux-ip.net  Sat Apr 11 17:05:37 2015
From: martin at linux-ip.net (Martin A. Brown)
Date: Sat, 11 Apr 2015 08:05:37 -0700
Subject: [Tutor] Hi
In-Reply-To: <20150411134112.GH5760@ando.pearwood.info>
References: <000001d07453$997a48a0$cc6ed9e0$@orange.mu>
 <20150411134112.GH5760@ando.pearwood.info>
Message-ID: <alpine.LSU.2.11.1504110801521.31213@znpeba>


Greetings Steven,

Much great advice snipped.

Is it possible (using U+1F600 through U+1F64F or otherwise) to offer 
a standing ovation for such a relevant, thorough, competent and 
well-written reply?

Thank you, as always,

-Martin

(You know, Steven, we had gotten so accustomed to your slapdash 
answers, that this one comes as a huge surprise.)

-- 
Martin A. Brown
http://linux-ip.net/

From vick1975 at orange.mu  Sat Apr 11 18:35:08 2015
From: vick1975 at orange.mu (Vick)
Date: Sat, 11 Apr 2015 20:35:08 +0400
Subject: [Tutor] Hi
In-Reply-To: <FCAD6842-22A1-4736-91B6-4102AA8D88DC@mac.com>
References: <000001d07453$997a48a0$cc6ed9e0$@orange.mu>
 <FCAD6842-22A1-4736-91B6-4102AA8D88DC@mac.com>
Message-ID: <000701d07475$7a833840$6f89a8c0$@orange.mu>

Hi,

Thanks for replying!

I understand as you said that since it was the very first language available
to them therefore scientists at large got stuck with it as I presume it
would have become the primary programming language example given in their
textbooks or study materials.

However your reply does not answer the first part of the proposition of my
question!

Given that all scientists like to code in Fortran but does it mean that
Python is inferior to it in terms of mathematical / scientific computation?

Thanks
Vick



-----Original Message-----
From: William Ray Wing [mailto:wrw at mac.com] 
Sent: Saturday, 11 April, 2015 17:40
To: Vick
Cc: William R. Wing; webmaster at python.org; tutor at python.org
Subject: Re: [Tutor] Hi


> On Apr 11, 2015, at 8:32 AM, Vick <vick1975 at orange.mu> wrote:
> 

[byte]

> However I recently talked to a guy online and he told me the 
> following, which actually intrigued and surprised me:
> 
> "The vast majority of numerical codes in science, including positional 
> astronomy, are written in Fortran and C/C++.  If you wish to use these 
> codes in minority and less efficient languages such as Python and VBA, 
> learning to translate this code into those languages is a skill you 
> will have to acquire."
> 
> The "codes" in question are referring to a query I posed to him 
> regarding the GUST86 theory on the computational position of Uranus' 
> natural satellites authored by Laskar and Jacobson in 1987. The "code" 
> is readily downloadable in Fortran at the IMCCE ftp site.
> 
> But his statement is insinuating that Python is inferior to Fortran as 
> a mathematical tool and that all of the scientific community prefers 
> to use Fortran.
> 
> My question is simple: Is he right or wrong?
> 
> 

He is probably right, but only because most large scientific codes have
historical roots that date back to the days when FORTRAN was the only
language readily available on the computers scientists used.  Even today,
FORTRAN compilers can frequently optimize typical scientific code to tighter
(faster) executable code than the compilers for other, more modern, richer
languages.  HOWEVER, that said, more and more scientific code is being
written with Python as the organizing language which calls mathematical
libraries written in FORTRAN.  Libraries like numpy make heavy use of
FORTRAN arrays, while allowing the scientific programmer to concentrate on
the higher levels of the science being modeled.

Bill

> 
> Thanks
> 
> Vick
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor


From steve at pearwood.info  Sat Apr 11 19:12:17 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 12 Apr 2015 03:12:17 +1000
Subject: [Tutor] Hi
In-Reply-To: <000701d07475$7a833840$6f89a8c0$@orange.mu>
References: <000001d07453$997a48a0$cc6ed9e0$@orange.mu>
 <FCAD6842-22A1-4736-91B6-4102AA8D88DC@mac.com>
 <000701d07475$7a833840$6f89a8c0$@orange.mu>
Message-ID: <20150411171216.GK5760@ando.pearwood.info>

On Sat, Apr 11, 2015 at 08:35:08PM +0400, Vick wrote:

> Given that all scientists like to code in Fortran but does it mean that
> Python is inferior to it in terms of mathematical / scientific computation?

Scientists do not like to code in Fortran. Anybody who tells you that is 
mistaken. If they wanted to be programmers, they would have become 
programmers, not scientists. If they *have* to program, they will, but 
they would rather do science, not programming.

No, Python is not inferior. It is just different. It is designed to have 
different strengths and weaknesses compared to Fortran.

Strengths of Fortran:

- You can write very fast, powerful numeric programs.
- Fortran excels at high-speed number-crunching.
- Fortran is an old language, in fact it is the first (and therefore 
  oldest) programming language. Because it has been around since the 
  1950s, there are lots of Fortran libraries you can use -- if you can 
  find them, or afford them.

Weaknesses of Fortran:

- It is difficult to write Fortran code.
- It is an old language which lacks modern programming features.
- It is hard to work with strings or do anything except 
  number-crunching.
- It is a very low-level language, which means you have to care about 
  things that have nothing to do with the problem you are trying to 
  solve, like memory.


Strengths of Python:

- It is a modern language with many modern features that Fortran lacks.
- It is easy to work with strings and other associated data structures.
- It is a high-level language that automatically looks after all the 
  boring book-keeping details, like memory.
- It excels at rapid application development.
- It excels at being a glue-language for calling pre-written C or 
  Fortran libraries.

Weaknesses:

- Pure Python code may be a bit slower that C or Fortran code. (But that 
  doesn't matter, if you can call a C or Fortran library to do the heavy 
  lifting, and leave Python to do the parts that C or Fortran struggle 
  with.)


When people tell you that "real scientists" write their code in Fortran, 
they are being macho pretentious fools. Do "real scientists" also make 
their own test tubes from sand they dug out of the ground themselves? 
No, of course not. It isn't 1800 any more, and the average scientist no 
more needs to program in Fortran than they need to grind their own 
lenses. Some scientists may still need to use Fortran, but that is a 
sign that they are still stuck with using ancient computer programs, not 
a good thing to be copied.

To give an analogy, Fortran is like flying a Suyez rocket. It is very 
difficult to learn to fly, but once you master it you can go into space 
in seconds. But it will takes years of training and months of 
preparation for each flight.

Python is like driving a car: it won't get you into space, but it takes 
weeks to learn to drive a car, not years, and you can jump in the car 
and drive to the shops with no preparation needed.

And you can get in your car and drive to the Suyez rocket, but you 
cannot get in the Suyez and fly to where you parked your car.

Which is better? Well, it depends. If you want to drive to the shops, 
the Suyez is completely useless. It costs fifty million dollars every 
time you use it, and you cannot even get to the shops.

If you want to spend six months writing a Fortran program to analysis 
your data, you can, and when you have finished, it will run in five 
seconds. Or you can spend six days writing it in Python, and it will run 
in five minutes. Which is better?

To be more precise: Python can use Fortran and C libraries to do the 
heavy lifting, the difficult work. Doing that from Fortran or C is a 
horrible experience: they are hard languages to learn, and hard to use. 
But using those libraries from Python is fast, and fun, and easy, and 
that means that scientists can spend more time doing science and less 
time trying to program the computer.



-- 
Steve

From alan.gauld at btinternet.com  Sat Apr 11 20:00:23 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 11 Apr 2015 19:00:23 +0100
Subject: [Tutor] Hi
In-Reply-To: <000001d07453$997a48a0$cc6ed9e0$@orange.mu>
References: <000001d07453$997a48a0$cc6ed9e0$@orange.mu>
Message-ID: <mgbnfm$tu2$1@ger.gmane.org>

On 11/04/15 13:32, Vick wrote:

> "The vast majority of numerical codes in science, including positional
> astronomy, are written in Fortran and C/C++.

True, because the vast majorioty of "scientific codes" (ie libraries) 
were written many years ago and are still maintained in the languages 
used back then. Mainly that was Fortran for science.

The vast majpority of *new* scientific code being written is not in 
Fortran (and not much in C either). In fact I don't know of any local 
university that still teaches Fortran as part of their normal
science or math syllabus.

Most new scientific work is done in Mathematica or similar high
level language and then translated when needed into a lower
level language like C or increasingly Java. (And if its
statistics often into R.)

> If you wish to use these codes in minority and less efficient
 > languages such as Python and VBA,

Minority - False. There are certainly more VBA programmers
than Fortan ones. And probably as many as there are C/C++
Python is only a little way behind Fortan if at all.
But if we limit ourselves to the scientific community
then its closer to being true.

>  learning to translatethis code into those languages
 > is a skill you will have to acquire."

Completely false. Almost all modern scripting languages
have mechanisms to call C libraries easily. (And high
quality  Fortran to C translators exist.)

Only if you need to write very high performance routines
that do not already exist - ie you are a research
scientist or mathematician - do you need to learn C
or Fortran. And even then its unlikely to be your
first choice.

> The "codes" in question are referring to a query I posed to him regarding
> the GUST86 theory on the computational position of Uranus' natural
> satellites authored by Laskar and Jacobson in 1987. The "code" is readily
> downloadable in Fortran at the IMCCE ftp site.

Have you investigated the SciPy libraries, and especially
the SciKit collection of specialist libraries. There
are several astro libraries in there.
Most are written in C but wrapped for use from Python.

> But his statement is insinuating that Python is inferior to Fortran as a
> mathematical tool

No, he quite correctly states that Python is less efficient
than C or Fortran for numerical analysis. That is true of
mainstream, Python. There are various projects attempting
to address that shortfall. But there are many dimensions
to the "goodness" of a programming language and "efficiency"
(ie runtime speed)  is only one of them. And on modern
computing hardware it is rarely the most important one.
Others include development speed (programming efficiency),
portability, reliability, connectivity, abstraction capability,
readability/maintainability, tool support etc.

To say any language is "inferior" to another needs to
be qualified by the dimension(s) being measured.
I see Steven has just posted a similar mail that goes
into the comparisons in more detail. So I'll stop
here :-)

> and that all of the scientific community prefers to use
> Fortran.

That depends who you talk to. I know many scientists who
swear by Mathematica and Matlab and don't use anything else.

> My question is simple: Is he right or wrong?

The answer is less simple: it depends...

Finally, for a more light-hearted take on the topic, see:

http://www.ee.ryerson.ca/~elf/hack/realmen.html

For maximum offence substitute Python for Pascal ;-)

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From cybervigilante at gmail.com  Sat Apr 11 19:41:28 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sat, 11 Apr 2015 10:41:28 -0700
Subject: [Tutor] list semantics
Message-ID: <CALRAYNX1HkRUCSWa8qC_MmZ8kVvwQkVH98NFGJVf1CYxMPkSgw@mail.gmail.com>

Why does the first range convert to a list, but not the second?

>>> p = list(range(1,20)), (range(40,59))
>>> p
([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
 range(40, 59))

-- 
Jim

"Stop, Harold! That bagel has radishes!"
"Thank God, Mary - you've saved me again!"

From lac at openend.se  Sat Apr 11 18:56:32 2015
From: lac at openend.se (Laura Creighton)
Date: Sat, 11 Apr 2015 18:56:32 +0200
Subject: [Tutor] On learning Fortran and C++ for scientific computing
In-Reply-To: Message from William Ray Wing <wrw@mac.com> of "Sat,
 11 Apr 2015 09:39:43 -0400." <FCAD6842-22A1-4736-91B6-4102AA8D88DC@mac.com>
References: <000001d07453$997a48a0$cc6ed9e0$@orange.mu><FCAD6842-22A1-4736-91B6-4102AA8D88DC@mac.com>
Message-ID: <201504111656.t3BGuWlD028763@fido.openend.se>

These days, most important scientific libraries are wrapped so that you
call call them directly from python. Google for "python bindings <name of
the library you want>" and see if you get any hits.  If you have a library
that doesn't have python bindings, you can probably make them.  Start
reading here:
http://intermediate-and-advanced-software-carpentry.readthedocs.org/en/latest/c++-wrapping.html
http://scicomp.stackexchange.com/questions/2283/which-package-should-i-use-to-wrap-modern-fortran-code-with-python

to see about wrapping C++ and Fortran code.

But chances are somebody has already done it.
And for astronomical calculations, I just use pyephem.
http://rhodesmill.org/pyephem/index.html

It is difficult, and usually pointless to argue with somebody who prefers to
use Fortran or C++ about using some other language.  People like what they
are used to.  Moreover, in the case of Fortran and C++, these languages are
significantly harder to use than Python, where harder, in this case,
means -- the code you write is more prone to errors.

Also, it is very easy to write inefficient programs in C++ or Fortran,
and scientists, who are not professional programmers are extremely prone
to doing this.  So while a Fortran or C++ library may be fast (if the
library author knew what he or she was doing, or the community has fixed
inefficiencies over the years) that doesn't mean that your own C++ or
Fortran code is guaranteed to be fast.

And, of course, if it takes you 5 times as long in your personal time to
write the code, do you actually care how fast the result runs?  For very
long running calculations, where time is money, the answer may be yes.
But if all you want to know is where Uranus is going to be next Thursday
so you can point your telescope at it, not a bit.

If you need something that runs faster than the standard version of
python, you may be able to get it with numpy and the other scientific
tools here: http://www.scipy.org/ or with pypy http://speed.pypy.org/ .
The number of problems where you can legitimately claim that you badly
need the speed that C++ and Fortran provide is shrinking all the time,
as machines grow faster.  Plus, in modern computing the new challenge is
to use multiple cores.

It's a very hard problem, and all the old C++ and Fortran libraries
were created with the assumption that there is only one core.  Right now
we don't actually know how to use multiple cores efficiently -- it is hot
research in computer science right now, with no particularly good answers.
But once we figure out how to do this, all the old C++ and Fortran
libraries are probably going to have to be rewritten with this in mind.
(A solution that doesn't require such re-writing would, of course be
highly desirable, but things are not looking very good on that front.)

If your real question is 'would it be desirable to learn C++ and Fortran
from a historical perspective, to get an understanding of how important
computational libraries in my field are structured', then I am the wrong
person to ask.  I knew both of these languages before there was a Python.
I think learning these langauges will indeed make understanding the
old libraries easier, but _using_ these languages to do real work isn't
needed.  Or rather, if you are one of the people who needs to use them,
then you would already know that you are, and why, and wouldn't be asking
the question.  The world is full of things to learn, so you need to do
your own prioritisation of Fortran vs everything else you haven't learned
yet. :)

Best of luck,
Laura Creighton

p.s. I gave this topic a more descriptive subject line than 'Hi' but it should
still thread with the original.

From joel.goldstick at gmail.com  Sat Apr 11 20:15:49 2015
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Sat, 11 Apr 2015 14:15:49 -0400
Subject: [Tutor] list semantics
In-Reply-To: <CALRAYNX1HkRUCSWa8qC_MmZ8kVvwQkVH98NFGJVf1CYxMPkSgw@mail.gmail.com>
References: <CALRAYNX1HkRUCSWa8qC_MmZ8kVvwQkVH98NFGJVf1CYxMPkSgw@mail.gmail.com>
Message-ID: <CAPM-O+z4iPJ2w0Lso8WGm0fEYNLQJqOwpA_i6dZ3FmPXnMEMyw@mail.gmail.com>

On Sat, Apr 11, 2015 at 1:41 PM, Jim Mooney <cybervigilante at gmail.com> wrote:
> Why does the first range convert to a list, but not the second?
>
>>>> p = list(range(1,20)), (range(40,59))
>>>> p
> ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
>  range(40, 59))
>
Assuming you are using python 3.x range is a generator, so it only
produces values if you iterate over it
> --
> Jim
>
> "Stop, Harold! That bagel has radishes!"
> "Thank God, Mary - you've saved me again!"
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Joel Goldstick
http://joelgoldstick.com

From timomlists at gmail.com  Sat Apr 11 20:17:10 2015
From: timomlists at gmail.com (Timo)
Date: Sat, 11 Apr 2015 20:17:10 +0200
Subject: [Tutor] list semantics
In-Reply-To: <CALRAYNX1HkRUCSWa8qC_MmZ8kVvwQkVH98NFGJVf1CYxMPkSgw@mail.gmail.com>
References: <CALRAYNX1HkRUCSWa8qC_MmZ8kVvwQkVH98NFGJVf1CYxMPkSgw@mail.gmail.com>
Message-ID: <55296526.2040101@gmail.com>

Op 11-04-15 om 19:41 schreef Jim Mooney:
> Why does the first range convert to a list, but not the second?
>
>>>> p = list(range(1,20)), (range(40,59))
>>>> p
> ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
>   range(40, 59))
>


I'm not sure I understand correctly. This is what the top of help(range) 
says:

<
Help on class range in module builtins:

class range(object)
  |  range(stop) -> range object
  |  range(start, stop[, step]) -> range object
  |
  |  Return a virtual sequence of numbers from start to stop by step.
 >

So range() returns a range object. In your example you convert the first 
one to a list with list(), but not the second, so it prints the range 
object.

 >>> range(2)
range(0, 2)
 >>> list(range(2))
[0, 1]

Timo

From steve at pearwood.info  Sat Apr 11 21:02:58 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 12 Apr 2015 05:02:58 +1000
Subject: [Tutor] list semantics
In-Reply-To: <CALRAYNX1HkRUCSWa8qC_MmZ8kVvwQkVH98NFGJVf1CYxMPkSgw@mail.gmail.com>
References: <CALRAYNX1HkRUCSWa8qC_MmZ8kVvwQkVH98NFGJVf1CYxMPkSgw@mail.gmail.com>
Message-ID: <20150411190257.GL5760@ando.pearwood.info>

On Sat, Apr 11, 2015 at 10:41:28AM -0700, Jim Mooney wrote:
> Why does the first range convert to a list, but not the second?
> 
> >>> p = list(range(1,20)), (range(40,59))
> >>> p
> ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
>  range(40, 59))

Why would the second convert to a list? You don't call list() on it.

You create a tuple, p, with two items. The first item is:

list(range(1, 20))

and the second item is:

range(40, 59)

so you end up with p being a tuple ([1, 2, 3, ..., 19], range(40, 59)).

The fact that you surround the second item with round brackets 
(parentheses) means nothing -- they just group the range object on its 
own. A bit like saying 1 + (2), which still evaluates as 3.



-- 
Steve

From steve at pearwood.info  Sat Apr 11 21:09:43 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 12 Apr 2015 05:09:43 +1000
Subject: [Tutor] list semantics
In-Reply-To: <CAPM-O+z4iPJ2w0Lso8WGm0fEYNLQJqOwpA_i6dZ3FmPXnMEMyw@mail.gmail.com>
References: <CALRAYNX1HkRUCSWa8qC_MmZ8kVvwQkVH98NFGJVf1CYxMPkSgw@mail.gmail.com>
 <CAPM-O+z4iPJ2w0Lso8WGm0fEYNLQJqOwpA_i6dZ3FmPXnMEMyw@mail.gmail.com>
Message-ID: <20150411190942.GM5760@ando.pearwood.info>

On Sat, Apr 11, 2015 at 02:15:49PM -0400, Joel Goldstick wrote:
> On Sat, Apr 11, 2015 at 1:41 PM, Jim Mooney <cybervigilante at gmail.com> wrote:
> > Why does the first range convert to a list, but not the second?
> >
> >>>> p = list(range(1,20)), (range(40,59))
> >>>> p
> > ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
> >  range(40, 59))
> >
> Assuming you are using python 3.x range is a generator, so it only
> produces values if you iterate over it

Almost correct, but not quite. range, like xrange in Python 2, is not a 
generator, but a custom-made lazy sequence object.

py> gen()  # This actually is a generator.
<generator object gen at 0xb7bd7914>
py> range(1, 10)  # This is not.
range(1, 10)


Range objects are special: not only do they produce values lazily as 
needed, but they also support len(), indexing, slicing, and membership 
testing, none of which generators are capable of doing:

py> r = range(1, 30, 3)
py> len(r)
10
py> r[8]  # indexing
25
py> r[2:5]  # slicing
range(7, 16, 3)
py> 9 in r  # membership testing
False
py> 10 in r
True

All those results are calculated lazily, without having to pre-calculate 
a potentially enormous list.


-- 
Steve

From breamoreboy at yahoo.co.uk  Sat Apr 11 21:20:14 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sat, 11 Apr 2015 20:20:14 +0100
Subject: [Tutor] list semantics
In-Reply-To: <20150411190257.GL5760@ando.pearwood.info>
References: <CALRAYNX1HkRUCSWa8qC_MmZ8kVvwQkVH98NFGJVf1CYxMPkSgw@mail.gmail.com>
 <20150411190257.GL5760@ando.pearwood.info>
Message-ID: <mgbs5g$5eq$1@ger.gmane.org>

On 11/04/2015 20:02, Steven D'Aprano wrote:
> On Sat, Apr 11, 2015 at 10:41:28AM -0700, Jim Mooney wrote:
>> Why does the first range convert to a list, but not the second?
>>
>>>>> p = list(range(1,20)), (range(40,59))
>>>>> p
>> ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
>>   range(40, 59))
>
> Why would the second convert to a list? You don't call list() on it.
>
> You create a tuple, p, with two items. The first item is:
>
> list(range(1, 20))
>
> and the second item is:
>
> range(40, 59)
>
> so you end up with p being a tuple ([1, 2, 3, ..., 19], range(40, 59)).
>
> The fact that you surround the second item with round brackets
> (parentheses) means nothing -- they just group the range object on its
> own. A bit like saying 1 + (2), which still evaluates as 3.
>

To follow up the tuple is created with a comma *NOT* parenthesis.  So in 
the example it is the second comma, the one immediately after the call 
to list(), that makes p a tuple.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From steve at pearwood.info  Sat Apr 11 21:21:53 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 12 Apr 2015 05:21:53 +1000
Subject: [Tutor] list semantics
In-Reply-To: <20150411190942.GM5760@ando.pearwood.info>
References: <CALRAYNX1HkRUCSWa8qC_MmZ8kVvwQkVH98NFGJVf1CYxMPkSgw@mail.gmail.com>
 <CAPM-O+z4iPJ2w0Lso8WGm0fEYNLQJqOwpA_i6dZ3FmPXnMEMyw@mail.gmail.com>
 <20150411190942.GM5760@ando.pearwood.info>
Message-ID: <20150411192153.GN5760@ando.pearwood.info>

On Sun, Apr 12, 2015 at 05:09:43AM +1000, Steven D'Aprano wrote:

> Almost correct, but not quite. range, like xrange in Python 2, is not a 
> generator, but a custom-made lazy sequence object.
> 
> py> gen()  # This actually is a generator.
> <generator object gen at 0xb7bd7914>
> py> range(1, 10)  # This is not.
> range(1, 10)

Oops, I forgot to show where gen() came from. Sorry about that, just a 
cut-and-paste error.

py> def gen():
...     yield 1
...
py> gen()  # This actually is a generator.
<generator object gen at 0xb7bd7914>



-- 
Steve

From joel.goldstick at gmail.com  Sat Apr 11 22:53:43 2015
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Sat, 11 Apr 2015 16:53:43 -0400
Subject: [Tutor] list semantics
In-Reply-To: <20150411192153.GN5760@ando.pearwood.info>
References: <CALRAYNX1HkRUCSWa8qC_MmZ8kVvwQkVH98NFGJVf1CYxMPkSgw@mail.gmail.com>
 <CAPM-O+z4iPJ2w0Lso8WGm0fEYNLQJqOwpA_i6dZ3FmPXnMEMyw@mail.gmail.com>
 <20150411190942.GM5760@ando.pearwood.info>
 <20150411192153.GN5760@ando.pearwood.info>
Message-ID: <CAPM-O+w8cB=JyjV9UPyxEhLQ_AWdW3cZJVAc-qr41NeV+7CGQA@mail.gmail.com>

On Sat, Apr 11, 2015 at 3:21 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Sun, Apr 12, 2015 at 05:09:43AM +1000, Steven D'Aprano wrote:
>
>> Almost correct, but not quite. range, like xrange in Python 2, is not a
>> generator, but a custom-made lazy sequence object.
>>
>> py> gen()  # This actually is a generator.
>> <generator object gen at 0xb7bd7914>
>> py> range(1, 10)  # This is not.
>> range(1, 10)
>
> Oops, I forgot to show where gen() came from. Sorry about that, just a
> cut-and-paste error.
>
> py> def gen():
> ...     yield 1
> ...
> py> gen()  # This actually is a generator.
> <generator object gen at 0xb7bd7914>
>
Thanks for the tip Steve
>
>
> --
> Steve
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Joel Goldstick
http://joelgoldstick.com

From omohundr at hawaii.edu  Sun Apr 12 01:15:53 2015
From: omohundr at hawaii.edu (Michael Omohundro)
Date: Sat, 11 Apr 2015 13:15:53 -1000
Subject: [Tutor] Changing spatial reference of shapefiles in folder and
 exporting to new folder
Message-ID: <CAPiXhqAW3Uohwp33cGZK8OzsVVYRKt1rg8rPdO_FjACb1jW7sQ@mail.gmail.com>

I want to assemble a script to: 1) input a folder with shapefiles with
different coordinate systems, 2) allow the user through a toolbox script to
choose a desired coordinate system, and then 3) export all the shapefiles
with the new coordinate system to a new folder.

So the problem is I don't know how to get the user to choose the coordinate
system they want when I create the script in toolbox.

Here is my code:

import arcpy


arcpy.env.workspace = arcpy.GetParameterAsText(0)

fcList = arcpy.ListFeatureClasses()

try:

    inFolder = arcpy.ListFeatureClasses()

    template = arcpy.GetParameteAsText(1)

    outFolder = arcpy.GetParameterAsText(2)


arcpy.AddMessage(template)

srf = arcpy.Describe(template).spatialReference.name


for fc in fcList:

    if srf.Name == "Unknown":

        # skip

        continue

    else:

        arcpy.Describe(fc).spatialReference.name != srf.name:
arcpy.Project_management (fc, outFolder + "\\" + fc, desc,
{transform_method}, {in_coor_system})


#

I have attached the window I am making in the toolbox to this email.

I also get this error when I run the script in the toolbox:

SyntaxError: invalid syntax (Final_Proj_DRAFT.py, line 16)Failed to
execute (SpatRefAutomation).

Line 16 of the code reads:

spatialRef = arcpy.Describe(inputFolder).spatialReference

Please help me.

From dyoo at hashcollision.org  Sun Apr 12 01:50:07 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 11 Apr 2015 16:50:07 -0700
Subject: [Tutor] Changing spatial reference of shapefiles in folder and
 exporting to new folder
In-Reply-To: <CAPiXhqAW3Uohwp33cGZK8OzsVVYRKt1rg8rPdO_FjACb1jW7sQ@mail.gmail.com>
References: <CAPiXhqAW3Uohwp33cGZK8OzsVVYRKt1rg8rPdO_FjACb1jW7sQ@mail.gmail.com>
Message-ID: <CAGZAPF7x0XPVwO+z6Xa2Xyfn3t3PjRhP+=N6uAs+8A2BM4=64g@mail.gmail.com>

Hi Michael,

Your question appears to be specifically about the ArcGIS library.
Unfortunately, I would assume very few of us have expertise on this
particular third-party mapping library; we're mostly a  forum for
teaching basic Python programming.  We can help on non-domain-specific
Python-learning issues, but for anything that's specific to ArcGIS,
you'll probably have more success talking to the ArcGIS folks.  I
believe you can find the ArcGIS folks at:
https://geonet.esri.com/community/developers/gis-developers/python


With that in mind: I will take a look at your program from a neutral
standpoint, assuming no domain-specific knowledge:

1.  Your program is malformed because it has a "try" block, but with
no "except" or "finally".  This is a syntax error.  The program is not
perfectly formed, so Python will not run your program until it has the
form of a correct program.  (Whether it does what you want is an
entirely different, "semantic" matter.)

When you're using 'try', your program is grammatically prompting the
setting up of an exception handler.

##################################
try:
    inFolder = arcpy.ListFeatureClasses()
    ...
##################################

... But your program has omitted what should happen if an exception
does occur!  What should happen if things go wrong?  Since that hasn't
been written in your program, it's ungrammatical.

See: https://docs.python.org/2/tutorial/errors.html for examples of
programs that have exception handlers to see how to correct this.
Alternatively: remove the exception handling altogether.  Often,
beginners put exception handling in because they don't realize that
error messages are awesome.  When there's an error, you usually *want*
to see the errors show up, at least while you are developing your
software.


2.  The line:

    template = arcpy.GetParameteAsText(1)

does not look correct because there's a inconsistently-spelled method
name "GetParameteAsText".

The line that follows immediately afterwards uses "GetParameterAsText":

    outFolder = arcpy.GetParameterAsText(2)

and so this inconsistency attracts my eye.  But because of the
domain-specificness, I can't say for certain that this is wrong, only
that it looks very not-quite-right.

From vick1975 at orange.mu  Sun Apr 12 08:25:54 2015
From: vick1975 at orange.mu (Vick)
Date: Sun, 12 Apr 2015 10:25:54 +0400
Subject: [Tutor] On learning Fortran and C++ for scientific computing
In-Reply-To: <201504111656.t3BGuWlD028763@fido.openend.se>
References: <000001d07453$997a48a0$cc6ed9e0$@orange.mu><FCAD6842-22A1-4736-91B6-4102AA8D88DC@mac.com>
 <201504111656.t3BGuWlD028763@fido.openend.se>
Message-ID: <000901d074e9$8829b0e0$987d12a0$@orange.mu>

Hello,

 

Thanks for the answer.

 

I quite get the drift of your explanations. But my question was looking for
a specific practical answer.

 

As my codes involve a lot of mathematical formulae and some of them require
ultra-high precision, hence I was looking for an answer that either Fortran
is better suited or Python is better at it.

 

One of the example, I'm thinking about is the commoving distance of redshift
in the universe and hence to calculate the radius of the observable
universe.see Hogg's paper on it:

 

http://arxiv.org/abs/astro-ph/9905116

 

This is a mathematical integration of several parameters in cosmology. This
particular calculation requires the best precision you can get because by
reducing it, you get different answers for the age of the universe and hence
the radius of the universe.

 

Example:

S for integration

S 0 to z ..> dz'/SQRT(omega_radiation (1+z)^4 + omega_matter (1+z)^3 +
omega_curvature (1+z)^2 + Omega_dark energy)

 

S 0 to 1e+31....> 1/sqrt(.000086 *(1+z)^4 + .282 * (1+z)^3 - .000086
*(1+z)^2   + .718)  if you try this integration you will get completely
wrong numbers on computing devices that do not possess ultra-high precision
and accuracy.

 

I had to use mpmath with precision of 250 and integration method called Tanh
Sinh Quadrature with accuracy 120 to get the desired results. I checked the
answer with Mathematica and they concur. But the calculation is done in
about 3 seconds on my laptop with intel core i5 at 2.5 GHz with 4 GB RAM.

 

So can Fortran crunch 250 digits numbers in an integration formula under 3
seconds with the same computing parameters as above? Or is Python better at
it?

 

Thanks

Vick

 

 

 

 

-----Original Message-----
From: Laura Creighton [mailto:lac at openend.se] 
Sent: Saturday, 11 April, 2015 20:57
To: William Ray Wing
Cc: Vick; webmaster at python.org; tutor at python.org; lac at openend.se
Subject: Re: [Tutor] On learning Fortran and C++ for scientific computing

 

These days, most important scientific libraries are wrapped so that you call
call them directly from python. Google for "python bindings <name of the
library you want>" and see if you get any hits.  If you have a library that
doesn't have python bindings, you can probably make them.  Start reading
here:

 
<http://intermediate-and-advanced-software-carpentry.readthedocs.org/en/late
st/c++-wrapping.html>
http://intermediate-and-advanced-software-carpentry.readthedocs.org/en/lates
t/c++-wrapping.html

 
<http://scicomp.stackexchange.com/questions/2283/which-package-should-i-use-
to-wrap-modern-fortran-code-with-python>
http://scicomp.stackexchange.com/questions/2283/which-package-should-i-use-t
o-wrap-modern-fortran-code-with-python

 

to see about wrapping C++ and Fortran code.

 

But chances are somebody has already done it.

And for astronomical calculations, I just use pyephem.

 <http://rhodesmill.org/pyephem/index.html>
http://rhodesmill.org/pyephem/index.html

 

It is difficult, and usually pointless to argue with somebody who prefers to
use Fortran or C++ about using some other language.  People like what they
are used to.  Moreover, in the case of Fortran and C++, these languages are
significantly harder to use than Python, where harder, in this case, means
-- the code you write is more prone to errors.

 

Also, it is very easy to write inefficient programs in C++ or Fortran, and
scientists, who are not professional programmers are extremely prone to
doing this.  So while a Fortran or C++ library may be fast (if the library
author knew what he or she was doing, or the community has fixed
inefficiencies over the years) that doesn't mean that your own C++ or
Fortran code is guaranteed to be fast.

 

And, of course, if it takes you 5 times as long in your personal time to
write the code, do you actually care how fast the result runs?  For very
long running calculations, where time is money, the answer may be yes.

But if all you want to know is where Uranus is going to be next Thursday so
you can point your telescope at it, not a bit.

 

If you need something that runs faster than the standard version of python,
you may be able to get it with numpy and the other scientific tools here:
<http://www.scipy.org/> http://www.scipy.org/ or with pypy
<http://speed.pypy.org/> http://speed.pypy.org/ .

The number of problems where you can legitimately claim that you badly need
the speed that C++ and Fortran provide is shrinking all the time, as
machines grow faster.  Plus, in modern computing the new challenge is to use
multiple cores.

 

It's a very hard problem, and all the old C++ and Fortran libraries were
created with the assumption that there is only one core.  Right now we don't
actually know how to use multiple cores efficiently -- it is hot research in
computer science right now, with no particularly good answers.

But once we figure out how to do this, all the old C++ and Fortran libraries
are probably going to have to be rewritten with this in mind.

(A solution that doesn't require such re-writing would, of course be highly
desirable, but things are not looking very good on that front.)

 

If your real question is 'would it be desirable to learn C++ and Fortran
from a historical perspective, to get an understanding of how important
computational libraries in my field are structured', then I am the wrong
person to ask.  I knew both of these languages before there was a Python.

I think learning these langauges will indeed make understanding the old
libraries easier, but _using_ these languages to do real work isn't needed.
Or rather, if you are one of the people who needs to use them, then you
would already know that you are, and why, and wouldn't be asking the
question.  The world is full of things to learn, so you need to do your own
prioritisation of Fortran vs everything else you haven't learned yet. :)

 

Best of luck,

Laura Creighton

 

p.s. I gave this topic a more descriptive subject line than 'Hi' but it
should still thread with the original.


From cybervigilante at gmail.com  Sun Apr 12 08:06:31 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sat, 11 Apr 2015 23:06:31 -0700
Subject: [Tutor] why no chaining?
Message-ID: <CALRAYNVHtsbGJo33n1iKjGaBrRw5iut2P3CYGMhnPFw61o=N_w@mail.gmail.com>

I thought I'd get [2,3,4,5] from this but instead I get nothing. Why isn't
it chaining?

>>> q = list(set([1,2,3,1,4,1,5,1,5])).remove(1)
>>> q
>>>

-- 
Jim

Today is the day that would have been yesterday if tomorrow was today

From cybervigilante at gmail.com  Sun Apr 12 08:41:59 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sat, 11 Apr 2015 23:41:59 -0700
Subject: [Tutor] Tutor Digest, Vol 134, Issue 32 - amazing range
Message-ID: <CALRAYNV-ZzU2btLv_zLHamKpZiSoPLS9n-Ep1Wd0ADtf5ipYFQ@mail.gmail.com>

> Range objects are special: not only do they produce values lazily as
> needed, but they also support len(), indexing, slicing, and membership
> testing, none of which generators are capable of doing:
>
> Steve
-----

That's really cool. Worth making a dumb mistake to find it out ;')

Jim
Today is the day that would have been yesterday if today was tomorrow

From alan.gauld at btinternet.com  Sun Apr 12 09:58:41 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 12 Apr 2015 08:58:41 +0100
Subject: [Tutor] why no chaining?
In-Reply-To: <CALRAYNVHtsbGJo33n1iKjGaBrRw5iut2P3CYGMhnPFw61o=N_w@mail.gmail.com>
References: <CALRAYNVHtsbGJo33n1iKjGaBrRw5iut2P3CYGMhnPFw61o=N_w@mail.gmail.com>
Message-ID: <mgd8jg$mhv$1@ger.gmane.org>

On 12/04/15 07:06, Jim Mooney wrote:
> I thought I'd get [2,3,4,5] from this but instead I get nothing. Why isn't
> it chaining?
>
>>>> q = list(set([1,2,3,1,4,1,5,1,5])).remove(1)
>>>> q
>>>>

Because that's just the way it was designed. It's common in
Python for methods that modify an object to return None.
I don't like it either, but that's the way it is.

You need to create a reference to the object then call
the method then use the modified object.

 >>> q = list(set([1,2,3,1,4,1,5,1,5]))
 >>> q.remove(1)
 >>> print q

Aside:
Normally you would use the help() function to find out
how methods work and what they return but sadly the
documentation for the in-place methods doesn't indicate
the return is None. Some of them have a warning that
its "IN PLACE" but remove does not. Which is a pity.

 >>> help([].sort)
Help on built-in function sort:

sort(...)
     L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
     cmp(x, y) -> -1, 0, 1
(END)

 >>> help([].remove)
Help on built-in function remove:

remove(...)
     L.remove(value) -- remove first occurrence of value.
     Raises ValueError if the value is not present.
(END)

Personally I think it would help if the first lines
for these methods read like:

remove(...) -> None
    L.remove...etc

As is the case with functions that return a value:
Help on built-in function pow in module __builtin__:

help(pow)
pow(...)
     pow(x, y[, z]) -> number

     With two arguments, equivalent to x**y.  With three arguments,
     equivalent to (x**y) % z, but may be more efficient (e.g.
     for longs).
(END)




HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From ben+python at benfinney.id.au  Sun Apr 12 10:05:16 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Sun, 12 Apr 2015 18:05:16 +1000
Subject: [Tutor] =?utf-8?q?Please_disable_=E2=80=9Cdigest=E2=80=9D_mode_in?=
 =?utf-8?q?_order_to_participate_=28was=3A_Tutor_Digest=2C_Vol_134=2C_Issu?=
 =?utf-8?q?e_32_-_amazing_range=29?=
References: <CALRAYNV-ZzU2btLv_zLHamKpZiSoPLS9n-Ep1Wd0ADtf5ipYFQ@mail.gmail.com>
Message-ID: <851tjpydoj.fsf@benfinney.id.au>

Jim Mooney <cybervigilante at gmail.com> writes:

> That's really cool. Worth making a dumb mistake to find it out ;')

Jim, you are evidently receiving ?digest? messages from this forum.

Please disable that in order to receive individual messages, so you can
participate properly: responding to individual messages that the rest of
us see.

Enabling ?digest? mode is only for when you are *certain* that you will
never at any point need to respond to any message from the forum. That's
not true, so should be turned off.

-- 
 \      ?I find the whole business of religion profoundly interesting. |
  `\     But it does mystify me that otherwise intelligent people take |
_o__)                                    it seriously.? ?Douglas Adams |
Ben Finney


From __peter__ at web.de  Sun Apr 12 10:43:35 2015
From: __peter__ at web.de (Peter Otten)
Date: Sun, 12 Apr 2015 10:43:35 +0200
Subject: [Tutor] On learning Fortran and C++ for scientific computing
References: <000001d07453$997a48a0$cc6ed9e0$@orange.mu>
 <FCAD6842-22A1-4736-91B6-4102AA8D88DC@mac.com>
 <201504111656.t3BGuWlD028763@fido.openend.se>
 <000901d074e9$8829b0e0$987d12a0$@orange.mu>
Message-ID: <mgdb7o$qcs$1@ger.gmane.org>

Vick wrote:

> So can Fortran crunch 250 digits numbers in an integration formula under 3
> seconds with the same computing parameters as above? Or is Python better
> at it?

So by better you mean faster. 

Pure CPython is usually much slower than Fortran, but as there are many 
optimised libraries written in C or sometimes even Fortran available for use 
with CPython, that often doesn't matter.

The mpmath documentation states that the library's performance can be 
improved by using gmp, so in this case the library you should rely on is 
gmpy or gmpy2.

Do you have one of these installed?

What does

$ python3 -c 'import mpmath.libmp; print(mpmath.libmp.BACKEND)'
gmpy

print? 


Once you have your script working with gmp you could simplify it to just the 
integration, and when you are down to 10 or 20 lines you could challenge 
your friend to write the Fortran equivalent.

If he answers he's not willing to spend a week on the superior Fortran 
solution, or if he comes up with something that takes 2.7 seconds you see 
that he was bullshitting you. 

If his code finishes in 0.1 second and with the correct result, you might 
consider learning the language -- but keep in mind that to save one hour of 
execution time you have to run the script more than 1200 times, and when you 
need 10 minutes longer to write the Fortran than the Python code you may 
still get a bad deal as your time usually costs more than that of a machine.

That said, even though I rarely write any C code knowing C does help me 
understand what happens in C programs (for example the Python interpreter) 
and generally broadens the horizon. Therefore I'd recommend learning C (or 
Fortran) anyway if you are interested in the computing part of your 
research.


From timomlists at gmail.com  Sun Apr 12 12:16:58 2015
From: timomlists at gmail.com (Timo)
Date: Sun, 12 Apr 2015 12:16:58 +0200
Subject: [Tutor] why no chaining?
In-Reply-To: <mgd8jg$mhv$1@ger.gmane.org>
References: <CALRAYNVHtsbGJo33n1iKjGaBrRw5iut2P3CYGMhnPFw61o=N_w@mail.gmail.com>
 <mgd8jg$mhv$1@ger.gmane.org>
Message-ID: <552A461A.1030503@gmail.com>

Op 12-04-15 om 09:58 schreef Alan Gauld:
>
> Aside:
> Normally you would use the help() function to find out
> how methods work and what they return but sadly the
> documentation for the in-place methods doesn't indicate
> the return is None. Some of them have a warning that
> its "IN PLACE" but remove does not. Which is a pity.
>
> >>> help([].sort)
> Help on built-in function sort:
>
> sort(...)
>     L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
>     cmp(x, y) -> -1, 0, 1
> (END)
>
> >>> help([].remove)
> Help on built-in function remove:
>
> remove(...)
>     L.remove(value) -- remove first occurrence of value.
>     Raises ValueError if the value is not present.
> (END)
>
> Personally I think it would help if the first lines
> for these methods read like:
>
> remove(...) -> None
>    L.remove...etc
Are you using Python 2? Because this is what I get in Python 3:

remove(...)
     L.remove(value) -> None -- remove first occurrence of value.
     Raises ValueError if the value is not present.

The same for help(list.sort) BTW.

Timo

From lac at openend.se  Sun Apr 12 13:29:56 2015
From: lac at openend.se (Laura Creighton)
Date: Sun, 12 Apr 2015 13:29:56 +0200
Subject: [Tutor] On learning Fortran and C++ for scientific computing
In-Reply-To: Message from "Vick" <vick1975@orange.mu> of "Sun,
 12 Apr 2015 10:25:54 +0400." <000901d074e9$8829b0e0$987d12a0$@orange.mu>
References: <000001d07453$997a48a0$cc6ed9e0$@orange.mu><FCAD6842-22A1-4736-91B6-4102AA8D88DC@mac.com>
 <201504111656.t3BGuWlD028763@fido.openend.se><000901d074e9$8829b0e0$987d12a0$@orange.mu>
Message-ID: <201504121129.t3CBTuXc028842@fido.openend.se>

In a message of Sun, 12 Apr 2015 10:25:54 +0400, "Vick" writes:
>S 0 to 1e+31....> 1/sqrt(.000086 *(1+z)^4 + .282 * (1+z)^3 - .000086
>*(1+z)^2   + .718)  if you try this integration you will get completely
>wrong numbers on computing devices that do not possess ultra-high precision
>and accuracy.

Python is as accurate as you can get, every bit as accurate as C++ or Fortran.

>I had to use mpmath with precision of 250 and integration method called Tanh
>Sinh Quadrature with accuracy 120 to get the desired results. I checked the
>answer with Mathematica and they concur. But the calculation is done in
>about 3 seconds on my laptop with intel core i5 at 2.5 GHz with 4 GB RAM.

>So can Fortran crunch 250 digits numbers in an integration formula under 3
>seconds with the same computing parameters as above? Or is Python better at
>it?

Some of us who were unhappy with the performance of python wrote pypy.
(I am one of the people, so very much biased here.)  PyPy uses a just-in-time
compiler to get its speed.  If you want to look at the speed of pypy vs the
speed of CPython (which is what we call the particular implementation(s)
of python you are using, because it is written in C) you can take a look
at these pages.  http://speed.pypy.org/

Click on a benchmark, and see the code, and see how much faster we are
than CPython.  Mathematical formulae are what we are very, very good
at.  Indeed we are often better than some old Fortran library -- so we
have users who are busy rewriting their code in Python in order to use
pypy for the increased speed of mathematical computation.  If all you
are doing is pure math -- and not going out, for instance and trying
to graph this thing at the same time -- then we can probably give you
speed which is equivalent to C.  But this assumes that you can write
this code where the heavy calculating is done inside a loop, which is
executed many times, because that is what PyPy optimises. If all you
have is straight in-line executed-one-time-only code, there will be no
speed win for you.

Also, the jit takes time to warm up.  It has to set up its own internal
bookkeeping before it can get to work on your code.  So if your code doesn't
take very long to run, it may run slower in pypy -- because the savings
your get are competely swallowed up in the setup costs.

However, it is easy to find out.  You can get pypy here:
http://pypy.org/download.html

It's a perfectly compliant, working python.  The version compatible with
3.2.5 is not as speedy as the one compatible with 2.7.  So just run your
python code with this -- it should run completely unchanged -- and see
how fast it is.

If you are still unhappy with the performance, post your code to
pypy-dev at python.org and we can give you suggestions on how to tune your
python code for better performance under pypy.  If you expose a place
where pypy ought to be fast, but isn't, we will fix pypy and get you
a working faster binary.

But I think any more talk about pypy belongs on the pypy-dev mailing list.

Laura Creighton

From lac at openend.se  Sun Apr 12 12:56:45 2015
From: lac at openend.se (Laura Creighton)
Date: Sun, 12 Apr 2015 12:56:45 +0200
Subject: [Tutor]
	=?utf-8?q?Please_disable_=E2=80=9Cdigest=E2=80=9D_mode_in?=
	=?utf-8?q?_order_to_participate_=28was=3A_Tutor_Digest=2C_Vol_134?=
	=?utf-8?q?=2C_Issue_32_-_amazing_range=29?=
In-Reply-To: Message from Ben Finney <ben+python@benfinney.id.au>
 of "Sun, 12 Apr 2015 18:05:16 +1000." <851tjpydoj.fsf@benfinney.id.au>
References: <CALRAYNV-ZzU2btLv_zLHamKpZiSoPLS9n-Ep1Wd0ADtf5ipYFQ@mail.gmail.com><851tjpydoj.fsf@benfinney.id.au>
Message-ID: <201504121056.t3CAujOD027839@fido.openend.se>

In a message of Sun, 12 Apr 2015 18:05:16 +1000, Ben Finney writes:
>Jim, you are evidently receiving ?digest? messages from this forum.
>
>Please disable that in order to receive individual messages, so you can
>participate properly: responding to individual messages that the rest of
>us see.
>
>Enabling ?digest? mode is only for when you are *certain* that you will
>never at any point need to respond to any message from the forum. That's
>not true, so should be turned off.

Or see if your mailer, like mine, has an option for bursting digests in
place. Bursting is splitting a digest into individual messages so that
you can reply to them individually. (Very few mailers do this, which
is a real shame.  And every one I know of calls this 'bursting'.)
Then please burst your digests before you reply to them.

Laura Creighton

From alan.gauld at btinternet.com  Sun Apr 12 13:39:40 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 12 Apr 2015 12:39:40 +0100
Subject: [Tutor] why no chaining?
In-Reply-To: <552A461A.1030503@gmail.com>
References: <CALRAYNVHtsbGJo33n1iKjGaBrRw5iut2P3CYGMhnPFw61o=N_w@mail.gmail.com>
 <mgd8jg$mhv$1@ger.gmane.org> <552A461A.1030503@gmail.com>
Message-ID: <mgdlhr$m1p$1@ger.gmane.org>

On 12/04/15 11:16, Timo wrote:

>> Personally I think it would help if the first lines
>> for these methods read like:
>>
>> remove(...) -> None
>>    L.remove...etc

> Are you using Python 2? Because this is what I get in Python 3:

Yes, I just fired up the default python which is 2.7.
I never thought to check what Python 3 help said.

Good to see its been addressed.,

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From cybervigilante at gmail.com  Sun Apr 12 20:03:07 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sun, 12 Apr 2015 11:03:07 -0700
Subject: [Tutor] still breaking chains
Message-ID: <CALRAYNVeXADuw_kKSbb6TC39mkTmvq+ULdmWRUefw9TnvOTfFA@mail.gmail.com>

If join returns a string, why am I getting a syntax error when I try  to
slice it?

>>> 'alfabeta'[2:5]
'fab'
>>> ''.join(['a', 'l', 'f', 'a', 'b', 'e', 't', 'a')[2:5]
SyntaxError: invalid syntax

-- 
Jim

From danny.yoo at gmail.com  Mon Apr 13 01:05:02 2015
From: danny.yoo at gmail.com (Danny Yoo)
Date: Sun, 12 Apr 2015 16:05:02 -0700
Subject: [Tutor] still breaking chains
In-Reply-To: <CALRAYNVeXADuw_kKSbb6TC39mkTmvq+ULdmWRUefw9TnvOTfFA@mail.gmail.com>
References: <CALRAYNVeXADuw_kKSbb6TC39mkTmvq+ULdmWRUefw9TnvOTfFA@mail.gmail.com>
Message-ID: <CAGZAPF6LH4VV74Wc-mthgYsKi0JO0ide97kFZzqrfF4FWr-M7g@mail.gmail.com>

On Apr 12, 2015 4:00 PM, "Jim Mooney" <cybervigilante at gmail.com> wrote:
>
> If join returns a string, why am I getting a syntax error when I try  to
> slice it?
>
> >>> 'alfabeta'[2:5]
> 'fab'
> >>> ''.join(['a', 'l', 'f', 'a', 'b', 'e', 't', 'a')[2:5]
> SyntaxError: invalid syntax

If you're seeing a SyntaxError, don't look for explanations that are
semantic.  Look for syntax.

In this case, note that the list of characters had not been closed with a
right bracket yet.

Best of wishes!

From ben+python at benfinney.id.au  Mon Apr 13 01:44:32 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Mon, 13 Apr 2015 09:44:32 +1000
Subject: [Tutor]
 =?utf-8?q?Please_disable_=E2=80=9Cdigest=E2=80=9D_mode_in?=
 =?utf-8?q?_order_to_participate?=
References: <CALRAYNV-ZzU2btLv_zLHamKpZiSoPLS9n-Ep1Wd0ADtf5ipYFQ@mail.gmail.com>
 <851tjpydoj.fsf@benfinney.id.au>
 <201504121056.t3CAujOD027839@fido.openend.se>
Message-ID: <85sic4x673.fsf@benfinney.id.au>

Laura Creighton <lac at openend.se> writes:

> In a message of Sun, 12 Apr 2015 18:05:16 +1000, Ben Finney writes:
> >Please disable that in order to receive individual messages, so you
> >can participate properly: responding to individual messages that the
> >rest of us see.
>
> Or see if your mailer, like mine, has an option for bursting digests
> in place. Bursting is splitting a digest into individual messages so
> that you can reply to them individually.

That's an interesting feature. It's not sufficient though: the resulting
messages lack the full header of each message, so any reply will not be
properly marked as a response to the original.

The only way to participate properly in a discussion on a mailing list
is to respond to the actual messages that were sent. And that's only
possible if you disable ?digest? mode beforehand.

-- 
 \          ?Those who write software only for pay should go hurt some |
  `\                 other field.? ?Erik Naggum, in _gnu.misc.discuss_ |
_o__)                                                                  |
Ben Finney


From ben+python at benfinney.id.au  Mon Apr 13 01:47:17 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Mon, 13 Apr 2015 09:47:17 +1000
Subject: [Tutor] still breaking chains
References: <CALRAYNVeXADuw_kKSbb6TC39mkTmvq+ULdmWRUefw9TnvOTfFA@mail.gmail.com>
Message-ID: <85oamsx62i.fsf@benfinney.id.au>

Jim Mooney <cybervigilante at gmail.com> writes:

> If join returns a string, why am I getting a syntax error when I try  to
> slice it?
>
> >>> 'alfabeta'[2:5]
> 'fab'
> >>> ''.join(['a', 'l', 'f', 'a', 'b', 'e', 't', 'a')[2:5]
> SyntaxError: invalid syntax

This demonstrates the primary problem with so-called ?chaining?. Your
statement is too complex, and you have misunderstood where in that
statement the error is.

Break the statement into at least two: get the result of the ?join?, and
then in the next statement slice that value. You'll see where the error
was.

One important principle to follow is to write your statements to be very
simple, so that when something goes wrong it is as easy as possible to
read the statement and understand what it *actually* says.

Chaining long strings of operations together in a single statement goes
directly against that principle, and hence is to be avoided.

-- 
 \       ?[T]he speed of response of the internet will re-introduce us |
  `\    to that from which our political systems have separated us for |
_o__)    so long, the consequences of our own actions.? ?Douglas Adams |
Ben Finney


From steve at pearwood.info  Mon Apr 13 03:11:52 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 13 Apr 2015 11:11:52 +1000
Subject: [Tutor] still breaking chains
In-Reply-To: <CALRAYNVeXADuw_kKSbb6TC39mkTmvq+ULdmWRUefw9TnvOTfFA@mail.gmail.com>
References: <CALRAYNVeXADuw_kKSbb6TC39mkTmvq+ULdmWRUefw9TnvOTfFA@mail.gmail.com>
Message-ID: <20150413011152.GO5760@ando.pearwood.info>

On Sun, Apr 12, 2015 at 11:03:07AM -0700, Jim Mooney wrote:

> If join returns a string, why am I getting a syntax error when I try  to
> slice it?

Because you have a syntax error. Syntax error means you have written 
something which the Python compiler cannot understand, because the 
syntax is wrong, mangled or confused, or something is missing from the 
line of code. (If the missing element is a closing bracket, brace or 
parethesis, the compiler may not report the error until the line *after* 
the offending line.) An English example:

"I would like a cup of coffee" -- correct syntax
"would coffee I cup like"  -- syntax error

Human beings are more flexible with syntax and can sometimes decipher 
rather mangled invalid sentences (e.g. most of us can understand Yoda) 
but programming language compilers are less flexible and require you to 
be pedantically correct:


+ 1 2   # syntax error
function(x y)  # syntax error
'-'.join['a', 'b')  # syntax error


This does not mean that Python cannot add numbers, call functions, or 
join substrings. It means the compiler cannot understand my mangled 
code. Fix the syntax:

1 + 2
function(x, y)
'-'.join(['a', 'b'])


In your example:

> >>> 'alfabeta'[2:5]
> 'fab'
> >>> ''.join(['a', 'l', 'f', 'a', 'b', 'e', 't', 'a')[2:5]
> SyntaxError: invalid syntax

I believe you have deleted what you might have thought was a blank line, 
but actually gives you a hint as to what the error is. When I try to run 
that, I get this:

py> ''.join(['a', 'l', 'f', 'a', 'b', 'e', 't', 'a')[2:5]
  File "<stdin>", line 1
    ''.join(['a', 'l', 'f', 'a', 'b', 'e', 't', 'a')[2:5]
                                                   ^
SyntaxError: invalid syntax


Look carefully at the "blank" line: it isn't actually blank. Way over on 
the right hand side you will see a caret ^ pointing to the spot where 
the compiler first noticed something it could not understand. In your 
email, it may not line up, but in the interactive interpreter the caret 
will line up with ) the closing round bracket. Why? Because before you 
close the method call ''.join( ) you have to close the list [ ]:

    ''.join([...])  # okay
    ''.join([...)  # syntax error

It is sad that the Python compiler does not report a more useful error 
message here. It would be awesome if it would report:

SyntaxError: missing closing bracket ]

but we should count our blessing that we get anything at all.



-- 
Steve

From robertvstepp at gmail.com  Mon Apr 13 04:21:06 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 12 Apr 2015 21:21:06 -0500
Subject: [Tutor] still breaking chains
In-Reply-To: <85oamsx62i.fsf@benfinney.id.au>
References: <CALRAYNVeXADuw_kKSbb6TC39mkTmvq+ULdmWRUefw9TnvOTfFA@mail.gmail.com>
 <85oamsx62i.fsf@benfinney.id.au>
Message-ID: <CANDiX9JLnZWRwNLP7WFkRuO02kAjiEZ3i1U18UyEF+pFFgfzdA@mail.gmail.com>

On Sun, Apr 12, 2015 at 6:47 PM, Ben Finney <ben+python at benfinney.id.au> wrote:

[...]

> One important principle to follow is to write your statements to be very
> simple, so that when something goes wrong it is as easy as possible to
> read the statement and understand what it *actually* says.

+1! This principle I have found to be incredibly helpful as I continue
to learn Python and better programming in general. Where it especially
pays dividends for me is when I must go back to where I was coding
after an extended interruption. I find that when I have followed this
principle I have a much better chance of *immediately* understanding
my intent, then when I have to decipher my thoughts from a "one-liner"
that might occupy less space, but where its complexity has me pausing
in thought to be sure I understand what I actually was trying to do.

-- 
boB

From cybervigilante at gmail.com  Mon Apr 13 01:44:22 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sun, 12 Apr 2015 16:44:22 -0700
Subject: [Tutor] still breaking chains
In-Reply-To: <CAGZAPF6LH4VV74Wc-mthgYsKi0JO0ide97kFZzqrfF4FWr-M7g@mail.gmail.com>
References: <CALRAYNVeXADuw_kKSbb6TC39mkTmvq+ULdmWRUefw9TnvOTfFA@mail.gmail.com>
 <CAGZAPF6LH4VV74Wc-mthgYsKi0JO0ide97kFZzqrfF4FWr-M7g@mail.gmail.com>
Message-ID: <CALRAYNXfe29jH0WuBE143jSwC3k4YJ+B6TaD9JuBpyV9OV-sow@mail.gmail.com>

On Apr 12, 2015 4:00 PM, "Jim Mooney" <cybervigilante at gmail.com> wrote:

> >
> > If join returns a string, why am I getting a syntax error when I try  to
> > slice it?
> >
> > >>> 'alfabeta'[2:5]
> > 'fab'
> > >>> ''.join(['a', 'l', 'f', 'a', 'b', 'e', 't', 'a')[2:5]
> > SyntaxError: invalid syntax
>
> If you're seeing a SyntaxError, don't look for explanations that are
> semantic.  Look for syntax.In this case, note that the list of characters
> had not been closed with a right bracket yet.
>
> Best of wishes!
>

Eeek! How did I miss that? Won't be the first time I confused mistyping
with misunderstanding ;')

-- 
Jim

From cybervigilante at gmail.com  Mon Apr 13 01:51:04 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sun, 12 Apr 2015 16:51:04 -0700
Subject: [Tutor]
	=?utf-8?q?Please_disable_=E2=80=9Cdigest=E2=80=9D_mode_in?=
	=?utf-8?q?_order_to_participate?=
In-Reply-To: <85sic4x673.fsf@benfinney.id.au>
References: <CALRAYNV-ZzU2btLv_zLHamKpZiSoPLS9n-Ep1Wd0ADtf5ipYFQ@mail.gmail.com>
 <851tjpydoj.fsf@benfinney.id.au>
 <201504121056.t3CAujOD027839@fido.openend.se>
 <85sic4x673.fsf@benfinney.id.au>
Message-ID: <CALRAYNUFdVCesFMmbc-z6uQpKWscN=qqqMaQCS7meECMUZSgjg@mail.gmail.com>

> That's an interesting feature. It's not sufficient though: the resulting
> messages lack the full header of each message, so any reply will not be
> properly marked as a response to the original.
>
> The only way to participate properly in a discussion on a mailing list
> is to respond to the actual messages that were sent. And that's only
> possible if you disable ?digest? mode beforehand.
> https://mail.python.org/mailman/listinfo/tutor
>

Well, I've disabled digest and assume I should Reply to All and underpost.
How does that look?

-- 
Jim

"Stop, Harold! That bagel has radishes!"
"Thank God, Mary - you've saved me again!"

From cybervigilante at gmail.com  Mon Apr 13 02:02:57 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sun, 12 Apr 2015 17:02:57 -0700
Subject: [Tutor] still breaking chains
In-Reply-To: <85oamsx62i.fsf@benfinney.id.au>
References: <CALRAYNVeXADuw_kKSbb6TC39mkTmvq+ULdmWRUefw9TnvOTfFA@mail.gmail.com>
 <85oamsx62i.fsf@benfinney.id.au>
Message-ID: <CALRAYNX=gpbtE2BF9LTS1NQPZeESQrfGCv4dkV=-hCEdq5fEfA@mail.gmail.com>

> Chaining long strings of operations together in a single statement goes
> directly against that principle, and hence is to be avoided.
>
> Ben Finney
>
>
A hard habit to break after using jQuery as a webmaster ;')
-- 
Jim

"Stop, Harold! That bagel has radishes!"
"Thank God, Mary - you've saved me again!"

From ben+python at benfinney.id.au  Mon Apr 13 10:35:52 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Mon, 13 Apr 2015 18:35:52 +1000
Subject: [Tutor]
 =?utf-8?q?Please_disable_=E2=80=9Cdigest=E2=80=9D_mode_in?=
 =?utf-8?q?_order_to_participate?=
References: <CALRAYNV-ZzU2btLv_zLHamKpZiSoPLS9n-Ep1Wd0ADtf5ipYFQ@mail.gmail.com>
 <851tjpydoj.fsf@benfinney.id.au>
 <201504121056.t3CAujOD027839@fido.openend.se>
 <85sic4x673.fsf@benfinney.id.au>
 <CALRAYNUFdVCesFMmbc-z6uQpKWscN=qqqMaQCS7meECMUZSgjg@mail.gmail.com>
Message-ID: <85y4lwv313.fsf@benfinney.id.au>

Jim Mooney <cybervigilante at gmail.com> writes:

> > The only way to participate properly in a discussion on a mailing
> > list is to respond to the actual messages that were sent. And that's
> > only possible if you disable ?digest? mode beforehand.
>
> Well, I've disabled digest and assume I should Reply to All and underpost.
> How does that look?

Looks great, thank you.

The cherry on top is: Preserve the attribution line (the line that says
who wrote the material you're quoting) on quoted material you keep.

Especially when there are several nested levels, ? like here ? keeping
the attribution lines matching the quoted material helps to make sense
of it all.

-- 
 \           ?The long-term solution to mountains of waste is not more |
  `\      landfill sites but fewer shopping centres.? ?Clive Hamilton, |
_o__)                                                _Affluenza_, 2005 |
Ben Finney


From alan.gauld at btinternet.com  Mon Apr 13 12:38:59 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 13 Apr 2015 11:38:59 +0100
Subject: [Tutor]
 =?utf-8?q?Please_disable_=E2=80=9Cdigest=E2=80=9D_mode_in?=
 =?utf-8?q?_order_to_participate?=
In-Reply-To: <CALRAYNUFdVCesFMmbc-z6uQpKWscN=qqqMaQCS7meECMUZSgjg@mail.gmail.com>
References: <CALRAYNV-ZzU2btLv_zLHamKpZiSoPLS9n-Ep1Wd0ADtf5ipYFQ@mail.gmail.com>
 <851tjpydoj.fsf@benfinney.id.au>
 <201504121056.t3CAujOD027839@fido.openend.se>
 <85sic4x673.fsf@benfinney.id.au>
 <CALRAYNUFdVCesFMmbc-z6uQpKWscN=qqqMaQCS7meECMUZSgjg@mail.gmail.com>
Message-ID: <mgg6c2$g2q$1@ger.gmane.org>

On 13/04/15 00:51, Jim Mooney wrote:

>> The only way to participate properly in a discussion on a mailing list
>> is to respond to the actual messages that were sent. And that's only
>> possible if you disable ?digest? mode beforehand.
>
> Well, I've disabled digest and assume I should Reply to All and underpost.
> How does that look?

Looks goods. BTW if you use digest to reduce clutter in the inbox you 
might find it worthwhile to create a folder for tutor mail and set up a 
rule to move all received mail from tutor to that folder. Then read that 
folder at your leisure.

Alternatively use the News feed from gmane.org

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From beachkidken at gmail.com  Mon Apr 13 14:11:46 2015
From: beachkidken at gmail.com (Ken G.)
Date: Mon, 13 Apr 2015 08:11:46 -0400
Subject: [Tutor] Function not returning 05 as string
Message-ID: <552BB282.3060303@gmail.com>

I am sure there is an simple explanation but when I input
5 (as integer), resulting in 05 (as string), I get zero as the end
result. When running the code:

START OF PROGRAM:
Enter the 1st number:  5

05

0
END OF PROGRAM:

START OF CODE:
import sys

def numberentry():
     print
     number01 = raw_input("Enter the 1st number:  ")
     if number01 == "0":
         sys.exit()
     if  len(number01) == 1:
         number01 = "0" + number01
     print
     print number01
     return(number01)

number01 = 0
numberentry()
print
print number01
END OF CODE:

From davea at davea.name  Mon Apr 13 14:18:55 2015
From: davea at davea.name (Dave Angel)
Date: Mon, 13 Apr 2015 08:18:55 -0400
Subject: [Tutor] Function not returning 05 as string
In-Reply-To: <552BB282.3060303@gmail.com>
References: <552BB282.3060303@gmail.com>
Message-ID: <552BB42F.4000009@davea.name>

On 04/13/2015 08:11 AM, Ken G. wrote:
> I am sure there is an simple explanation but when I input
> 5 (as integer), resulting in 05 (as string), I get zero as the end
> result. When running the code:
>
> START OF PROGRAM:
> Enter the 1st number:  5
>
> 05
>
> 0
> END OF PROGRAM:
>
> START OF CODE:
> import sys
>
> def numberentry():
>      print
>      number01 = raw_input("Enter the 1st number:  ")
>      if number01 == "0":
>          sys.exit()
>      if  len(number01) == 1:
>          number01 = "0" + number01
>      print
>      print number01
>      return(number01)
>
> number01 = 0

What is this line intended to do?

> numberentry()

Where are you intending to store the return value?  Currently, you're 
just throwing it away.

> print
> print number01

This variable has no relation to the one in the function.  In fact, I'd 
recommend you use a different name, to make that clear.

> END OF CODE:


-- 
DaveA

From jarod_v6 at libero.it  Mon Apr 13 14:29:07 2015
From: jarod_v6 at libero.it (jarod_v6 at libero.it)
Date: Mon, 13 Apr 2015 14:29:07 +0200 (CEST)
Subject: [Tutor] Regular expression on python
Message-ID: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>

Dear all.
I would like to extract from some file some data.
The line I'm interested is this:

Input Read Pairs: 2127436 Both Surviving: 1795091 (84.38%) Forward Only Surviving: 17315 (0.81%) Reverse Only Surviving: 6413 (0.30%) Dropped: 308617 (14.51%)



 with open("255.trim.log","r") as p:
    for i in p:
        lines= i.strip("\t")
        if lines.startswith("Input"):
            tp = lines.split("\t")
            print re.findall("Input\d",str(tp))

So I started to find ":" from the row:
 with open("255.trim.log","r") as p:
    for i in p:
        lines= i.strip("\t")
        if lines.startswith("Input"):
            tp = lines.split("\t")
            print re.findall(":",str(tp[0]))

And I'm able to find, but when I try to take the number using \d not work. Someone can explain why?
How can extract the numbers from this row.?
thanks so much=


From beachkidken at gmail.com  Mon Apr 13 14:34:09 2015
From: beachkidken at gmail.com (Ken G.)
Date: Mon, 13 Apr 2015 08:34:09 -0400
Subject: [Tutor] Function not returning 05 as string
In-Reply-To: <552BB42F.4000009@davea.name>
References: <552BB282.3060303@gmail.com> <552BB42F.4000009@davea.name>
Message-ID: <552BB7C1.4040705@gmail.com>



On 04/13/2015 08:18 AM, Dave Angel wrote:
> On 04/13/2015 08:11 AM, Ken G. wrote:
>> I am sure there is an simple explanation but when I input
>> 5 (as integer), resulting in 05 (as string), I get zero as the end
>> result. When running the code:
>>
>> START OF PROGRAM:
>> Enter the 1st number:  5
>>
>> 05
>>
>> 0
>> END OF PROGRAM:
>>
>> START OF CODE:
>> import sys
>>
>> def numberentry():
>>      print
>>      number01 = raw_input("Enter the 1st number:  ")
>>      if number01 == "0":
>>          sys.exit()
>>      if  len(number01) == 1:
>>          number01 = "0" + number01
>>      print
>>      print number01
>>      return(number01)
>>
>> number01 = 0
>
> What is this line intended to do?
NameError: name 'number01' is not defined

>
>> numberentry()
>
> Where are you intending to store the return value?  Currently, you're 
> just throwing it away.
I am not sending anything to the def routine but expected an answer in 
return.
>
>> print
>> print number01
>
> This variable has no relation to the one in the function.  In fact, 
> I'd recommend you use a different name, to make that clear.
Do not use return at end of routine? I am lost there.
>
>> END OF CODE:
>
>
Thanks for answering.

Ken

From __peter__ at web.de  Mon Apr 13 14:44:09 2015
From: __peter__ at web.de (Peter Otten)
Date: Mon, 13 Apr 2015 14:44:09 +0200
Subject: [Tutor] Function not returning 05 as string
References: <552BB282.3060303@gmail.com>
Message-ID: <mggdmr$cfe$1@ger.gmane.org>

Ken G. wrote:

> I am sure there is an simple explanation but when I input
> 5 (as integer), resulting in 05 (as string), I get zero as the end
> result. When running the code:
> 
> START OF PROGRAM:
> Enter the 1st number:  5
> 
> 05
> 
> 0
> END OF PROGRAM:
> 
> START OF CODE:
> import sys
> 
> def numberentry():
>      print
>      number01 = raw_input("Enter the 1st number:  ")
>      if number01 == "0":
>          sys.exit()
>      if  len(number01) == 1:
>          number01 = "0" + number01
>      print
>      print number01
>      return(number01)
> 
> number01 = 0
> numberentry()
> print
> print number01
> END OF CODE:

Let's simplify that and run it in the interactive interpreter:

>>> x = 0
>>> def f():
...     x = 5
...     print x
... 
>>> f()
5
>>> x
0

You are seeing two different values because there are two separate 
namespaces. The x = 0 lives in the "global" namespace of the module while 
the other x = 5 exists in the "local" namespace of the function, is only 
visible from a specific invocation of f() and only while that specific 
invocation of f() is executed.

If you want see the value of a global variable from within a function you 
must not rebind it:

>>> def g():
...     print x
... 
>>> f()
5
>>> x = 42
>>> f()
5

If you want to update a global variable you should do that explicitly

>>> def h():
...     return "foo"
... 
>>> x = h()
>>> x
'foo'

but there is also the option to declare it as global inside the function:

>>> def k():
...     global x
...     x = "bar"
... 
>>> k()
>>> x
'bar'

The global keyword is generally overused by newbies and tends to make your 
programs hard to maintain.

Try it a few times to ensure that you understand how it works -- and then 
forget about it and never use it again ;)

Back to your original code -- assuming that you want to update the global 
name 'number01' you could rewrite it like this:


def numberentry():
     digit = raw_input("Enter the 1st number:  ")
     if len(digit) != 1 or not digit.isdigit():
         raise ValueError("Not an allowed input: {!r}".format(digit))
     return digit.zfill(2)

number01 = numberentry()
if number01 != "00":
    print number01



From dpalao.python at gmail.com  Mon Apr 13 14:46:08 2015
From: dpalao.python at gmail.com (David Palao)
Date: Mon, 13 Apr 2015 14:46:08 +0200
Subject: [Tutor] Function not returning 05 as string
In-Reply-To: <552BB282.3060303@gmail.com>
References: <552BB282.3060303@gmail.com>
Message-ID: <CAKUKWzk46Y9WokL4c2DDNbv923ftf9J1Jn4HC8Jkb6-j9CoFow@mail.gmail.com>

Hello,
In the code that you posted, as it is, you are:
1) defining a function (numberentry)
2) defining a global variable (number01) and setting it to 0
3) calling numberentry discarding the result
4) printing the value of the global variable number01

I would guess that you want to store the result of the function and
print it. Is that correct?

Best

2015-04-13 14:11 GMT+02:00 Ken G. <beachkidken at gmail.com>:
> I am sure there is an simple explanation but when I input
> 5 (as integer), resulting in 05 (as string), I get zero as the end
> result. When running the code:
>
> START OF PROGRAM:
> Enter the 1st number:  5
>
> 05
>
> 0
> END OF PROGRAM:
>
> START OF CODE:
> import sys
>
> def numberentry():
>     print
>     number01 = raw_input("Enter the 1st number:  ")
>     if number01 == "0":
>         sys.exit()
>     if  len(number01) == 1:
>         number01 = "0" + number01
>     print
>     print number01
>     return(number01)
>
> number01 = 0
> numberentry()
> print
> print number01
> END OF CODE:
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From steve at pearwood.info  Mon Apr 13 14:56:32 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 13 Apr 2015 22:56:32 +1000
Subject: [Tutor] Function not returning 05 as string
In-Reply-To: <552BB282.3060303@gmail.com>
References: <552BB282.3060303@gmail.com>
Message-ID: <20150413125631.GA5663@ando.pearwood.info>

On Mon, Apr 13, 2015 at 08:11:46AM -0400, Ken G. wrote:
> I am sure there is an simple explanation but when I input
> 5 (as integer), resulting in 05 (as string), I get zero as the end
> result. When running the code:

> number01 = 0

Here you set the variable "number01" to the int 0.

> numberentry()

Here you call the function. It returns "05", but you don't do anything 
with it, so it just gets dropped on the floor and thrown away.

> print
> print number01

Here you print the variable number01, which is still the int 0, 
unchanged.

I think where you are mislead is that you are not aware, or have 
forgotten, that global variables and local variables are different. So a 
variable "x" outside of a function and a variable "x" inside a function 
are different variables. Think of functions being like Los Vegas: "what 
happens in Vegas, stays in Vegas" -- function local variables don't leak 
out and have effects outside of the function except via the "return" 
statement, and even then only if the caller assigns the result to 
another variable:

function()  # return result is thrown away
x = function()  # return result is assigned to x


The other way to have an effect outside of the function is to use global 
variables, and the global keyword. This is occasionally necessary, but I 
strongly recommend against it: it is poor programming practice and a bad 
habit to get into.


-- 
Steve

From beachkidken at gmail.com  Mon Apr 13 15:10:55 2015
From: beachkidken at gmail.com (Ken G.)
Date: Mon, 13 Apr 2015 09:10:55 -0400
Subject: [Tutor] Function not returning 05 as string [SOLVED]
In-Reply-To: <20150413125631.GA5663@ando.pearwood.info>
References: <552BB282.3060303@gmail.com>
 <20150413125631.GA5663@ando.pearwood.info>
Message-ID: <552BC05F.8080702@gmail.com>



On 04/13/2015 08:56 AM, Steven D'Aprano wrote:
> On Mon, Apr 13, 2015 at 08:11:46AM -0400, Ken G. wrote:
>> I am sure there is an simple explanation but when I input
>> 5 (as integer), resulting in 05 (as string), I get zero as the end
>> result. When running the code:
>> number01 = 0
> Here you set the variable "number01" to the int 0.
>
>> numberentry()
> Here you call the function. It returns "05", but you don't do anything
> with it, so it just gets dropped on the floor and thrown away.
>
>> print
>> print number01
> Here you print the variable number01, which is still the int 0,
> unchanged.
>
> I think where you are mislead is that you are not aware, or have
> forgotten, that global variables and local variables are different. So a
> variable "x" outside of a function and a variable "x" inside a function
> are different variables. Think of functions being like Los Vegas: "what
> happens in Vegas, stays in Vegas" -- function local variables don't leak
> out and have effects outside of the function except via the "return"
> statement, and even then only if the caller assigns the result to
> another variable:
>
> function()  # return result is thrown away
> x = function()  # return result is assigned to x
>
>
> The other way to have an effect outside of the function is to use global
> variables, and the global keyword. This is occasionally necessary, but I
> strongly recommend against it: it is poor programming practice and a bad
> habit to get into.
>
>
Thanks for all the replies. I will keep at it. Again, thanks.

Ken

From jarod_v6 at libero.it  Mon Apr 13 16:30:50 2015
From: jarod_v6 at libero.it (jarod_v6 at libero.it)
Date: Mon, 13 Apr 2015 16:30:50 +0200 (CEST)
Subject: [Tutor] R: Tutor Digest, Vol 134, Issue 36
Message-ID: <1183122906.1592361428935450788.JavaMail.httpd@webmail-58.iol.local>

At the moment I use this way to resolve my question:
 re.findall(r'(\w+):\W(\d+)',str(tp[0]))

However please gave me you suggestion on how to improve my ability to use  
regular expression on python
Thanks so much!



From vick1975 at orange.mu  Mon Apr 13 18:45:21 2015
From: vick1975 at orange.mu (Vick)
Date: Mon, 13 Apr 2015 20:45:21 +0400
Subject: [Tutor] On learning Fortran and C++ for scientific computing
In-Reply-To: <201504121129.t3CBTuXc028842@fido.openend.se>
References: <000001d07453$997a48a0$cc6ed9e0$@orange.mu><FCAD6842-22A1-4736-91B6-4102AA8D88DC@mac.com>
 <201504111656.t3BGuWlD028763@fido.openend.se><000901d074e9$8829b0e0$987d12a0$@orange.mu>
 <201504121129.t3CBTuXc028842@fido.openend.se>
Message-ID: <000001d07609$4306b280$c9141780$@orange.mu>

Hi,

 

Thanks

 

Vick

 

-----Original Message-----
From: Laura Creighton [mailto:lac at openend.se] 
Sent: Sunday, 12 April, 2015 15:30
To: Vick
Cc: 'Laura Creighton'; 'William Ray Wing'; webmaster at python.org;
tutor at python.org; lac at openend.se
Subject: Re: [Tutor] On learning Fortran and C++ for scientific computing

 

In a message of Sun, 12 Apr 2015 10:25:54 +0400, "Vick" writes:

>S 0 to 1e+31....> 1/sqrt(.000086 *(1+z)^4 + .282 * (1+z)^3 - .000086

>*(1+z)^2   + .718)  if you try this integration you will get completely

>wrong numbers on computing devices that do not possess ultra-high 

>precision and accuracy.

 

Python is as accurate as you can get, every bit as accurate as C++ or
Fortran.

 

>I had to use mpmath with precision of 250 and integration method called 

>Tanh Sinh Quadrature with accuracy 120 to get the desired results. I 

>checked the answer with Mathematica and they concur. But the 

>calculation is done in about 3 seconds on my laptop with intel core i5 at
2.5 GHz with 4 GB RAM.

 

>So can Fortran crunch 250 digits numbers in an integration formula 

>under 3 seconds with the same computing parameters as above? Or is 

>Python better at it?

 

Some of us who were unhappy with the performance of python wrote pypy.

(I am one of the people, so very much biased here.)  PyPy uses a
just-in-time compiler to get its speed.  If you want to look at the speed of
pypy vs the speed of CPython (which is what we call the particular
implementation(s) of python you are using, because it is written in C) you
can take a look at these pages.   <http://speed.pypy.org/>
http://speed.pypy.org/

 

Click on a benchmark, and see the code, and see how much faster we are than
CPython.  Mathematical formulae are what we are very, very good at.  Indeed
we are often better than some old Fortran library -- so we have users who
are busy rewriting their code in Python in order to use pypy for the
increased speed of mathematical computation.  If all you are doing is pure
math -- and not going out, for instance and trying to graph this thing at
the same time -- then we can probably give you speed which is equivalent to
C.  But this assumes that you can write this code where the heavy
calculating is done inside a loop, which is executed many times, because
that is what PyPy optimises. If all you have is straight in-line
executed-one-time-only code, there will be no speed win for you.

 

Also, the jit takes time to warm up.  It has to set up its own internal
bookkeeping before it can get to work on your code.  So if your code doesn't
take very long to run, it may run slower in pypy -- because the savings your
get are competely swallowed up in the setup costs.

 

However, it is easy to find out.  You can get pypy here:

 <http://pypy.org/download.html> http://pypy.org/download.html

 

It's a perfectly compliant, working python.  The version compatible with

3.2.5 is not as speedy as the one compatible with 2.7.  So just run your
python code with this -- it should run completely unchanged -- and see how
fast it is.

 

If you are still unhappy with the performance, post your code to
<mailto:pypy-dev at python.org> pypy-dev at python.org and we can give you
suggestions on how to tune your python code for better performance under
pypy.  If you expose a place where pypy ought to be fast, but isn't, we will
fix pypy and get you a working faster binary.

 

But I think any more talk about pypy belongs on the pypy-dev mailing list.

 

Laura Creighton


From cbc at unc.edu  Mon Apr 13 19:48:41 2015
From: cbc at unc.edu (Chris Calloway)
Date: Mon, 13 Apr 2015 13:48:41 -0400
Subject: [Tutor] Python and Django Web Engineering Class
Message-ID: <552C0179.6040103@unc.edu>

Not for everybody, but this just popped up in my neck of the woods, 
organized by members of my Python user group, and I though there might 
be a few people here looking for something like this:

http://astrocodeschool.com/

It's one of those intensive multi-week code school formats that aren't 
inexpensive. But it's taught by the primary Python instructor at UNC. 
The school is also licensed by the State of North Carolina and sponsored 
by Caktus Group, the largest Django development firm.

-- 
Sincerely,

Chris Calloway, Applications Analyst
UNC Renaissance Computing Institute
100 Europa Drive, Suite 540, Chapel Hill, NC 27517
(919) 599-3530

From lac at openend.se  Mon Apr 13 16:01:52 2015
From: lac at openend.se (Laura Creighton)
Date: Mon, 13 Apr 2015 16:01:52 +0200
Subject: [Tutor]
	=?utf-8?q?Please_disable_=E2=80=9Cdigest=E2=80=9D_mode_in?=
	=?utf-8?q?_order_to_participate?=
In-Reply-To: Message from Jim Mooney <cybervigilante@gmail.com> of "Sun,
 12 Apr 2015 16:51:04 -0700."
 <CALRAYNUFdVCesFMmbc-z6uQpKWscN=qqqMaQCS7meECMUZSgjg@mail.gmail.com>
References: <CALRAYNV-ZzU2btLv_zLHamKpZiSoPLS9n-Ep1Wd0ADtf5ipYFQ@mail.gmail.com>
 <851tjpydoj.fsf@benfinney.id.au>
 <201504121056.t3CAujOD027839@fido.openend.se>
 <85sic4x673.fsf@benfinney.id.au><CALRAYNUFdVCesFMmbc-z6uQpKWscN=qqqMaQCS7meECMUZSgjg@mail.gmail.com>
Message-ID: <201504131401.t3DE1q43012657@fido.openend.se>

In a message of Sun, 12 Apr 2015 16:51:04 -0700, Jim Mooney writes:

>Well, I've disabled digest and assume I should Reply to All and underpost.
>How does that look?
>
>-- 
>Jim

Looks great here.

Laura

From alan.gauld at btinternet.com  Mon Apr 13 20:42:03 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 13 Apr 2015 19:42:03 +0100
Subject: [Tutor] Regular expression on python
In-Reply-To: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
Message-ID: <mgh2lq$2kf$1@ger.gmane.org>

On 13/04/15 13:29, jarod_v6 at libero.it wrote:

> Input Read Pairs: 2127436 Both Surviving: 1795091 (84.38%) Forward Only Surviving: 17315 (0.81%) Reverse Only Surviving: 6413 (0.30%) Dropped: 308617 (14.51%)

Its not clear where the tabs are in this line.
But if they are after the numbers, like so:

Input Read Pairs: 2127436 \t
Both Surviving: 1795091 (84.38%) \t
Forward Only Surviving: 17315 (0.81%) \t
Reverse Only Surviving: 6413 (0.30%) \t
Dropped: 308617 (14.51%)

Then you may not need to use regular expressions.
Simply split by tab then split by :
And if the 'number' contains parens split again by space

>   with open("255.trim.log","r") as p:
>      for i in p:
>          lines= i.strip("\t")

lines is a bad name here since its only a single line. In fact I'd lose 
the 'i' variable and just use

for line in p:

>          if lines.startswith("Input"):
>              tp = lines.split("\t")
>              print re.findall("Input\d",str(tp))

Input is not followed by a number. You need a more powerful pattern.
Which is why I recommend trying to solve it as far as possible
without using regex.

> So I started to find ":" from the row:
>   with open("255.trim.log","r") as p:
>      for i in p:
>          lines= i.strip("\t")
>          if lines.startswith("Input"):
>              tp = lines.split("\t")
>              print re.findall(":",str(tp[0]))

Does finding the colons really help much?
Or at least, does it help any more than splitting by colon would?

> And I'm able to find, but when I try to take the number using \d not work.
> Someone can explain why?

Because your pattern doesn't match the string.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Mon Apr 13 21:14:16 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 13 Apr 2015 20:14:16 +0100
Subject: [Tutor] Regular expression on python
In-Reply-To: <mgh2lq$2kf$1@ger.gmane.org>
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
 <mgh2lq$2kf$1@ger.gmane.org>
Message-ID: <mgh4i7$vpt$1@ger.gmane.org>

On 13/04/15 19:42, Alan Gauld wrote:

>>          if lines.startswith("Input"):
>>              tp = lines.split("\t")
>>              print re.findall("Input\d",str(tp))
>
> Input is not followed by a number. You need a more powerful pattern.
> Which is why I recommend trying to solve it as far as possible
> without using regex.

I also just realised that you call split there then take the str() of 
the result. That means you are searching the string representation
of a list, which doesn't seem to make much sense?


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From steve at pearwood.info  Tue Apr 14 03:48:16 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Tue, 14 Apr 2015 11:48:16 +1000
Subject: [Tutor] Regular expression on python
In-Reply-To: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
Message-ID: <20150414014816.GC5663@ando.pearwood.info>

On Mon, Apr 13, 2015 at 02:29:07PM +0200, jarod_v6 at libero.it wrote:
> Dear all.
> I would like to extract from some file some data.
> The line I'm interested is this:
> 
> Input Read Pairs: 2127436 Both Surviving: 1795091 (84.38%) Forward 
> Only Surviving: 17315 (0.81%) Reverse Only Surviving: 6413 (0.30%) 
> Dropped: 308617 (14.51%)


    Some people, when confronted with a problem, think "I know, I'll 
    use regular expressions." Now they have two problems.
    -- Jamie Zawinski
?
I swear that Perl has been a blight on an entire generation of 
programmers. All they know is regular expressions, so they turn every 
data processing problem into a regular expression. Or at least they 
*try* to. As you have learned, regular expressions are hard to read, 
hard to write, and hard to get correct.

Let's write some Python code instead.


def extract(line):
    # Extract key:number values from the string.
    line = line.strip()  # Remove leading and trailing whitespace.
    words = line.split()
    accumulator = []  # Collect parts of the string we care about.
    for word in words:
        if word.startswith('(') and word.endswith('%)'):
            # We don't care about percentages in brackets.
            continue
        try:
            n = int(word)
        except ValueError:
            accumulator.append(word)
        else:
            accumulator.append(n)
    # Now accumulator will be a list of strings and ints:
    # e.g. ['Input', 'Read', 'Pairs:', 1234, 'Both', 'Surviving:', 1000]
    # Collect consecutive strings as the key, int to be the value.
    results = {}
    keyparts = []
    for item in accumulator:
        if isinstance(item, int):
            key = ' '.join(keyparts)
            keyparts = []
            if key.endswith(':'):
                key = key[:-1]
            results[key] = item
        else:
            keyparts.append(item)
    # When we have finished processing, the keyparts list should be empty.
    if keyparts:
        extra = ' '.join(keyparts)
        print('Warning: found extra text at end of line "%s".' % extra)
    return results



Now let me test it:

py> line = ('Input Read Pairs: 2127436 Both Surviving: 1795091'
...         ' (84.38%) Forward Only Surviving: 17315 (0.81%)'
...         ' Reverse Only Surviving: 6413 (0.30%) Dropped:'
...         ' 308617 (14.51%)\n')
py>
py> print(line)
Input Read Pairs: 2127436 Both Surviving: 1795091 (84.38%) Forward 
Only Surviving: 17315 (0.81%) Reverse Only Surviving: 6413 (0.30%) 
Dropped: 308617 (14.51%)

py> extract(line)
{'Dropped': 308617, 'Both Surviving': 1795091, 'Reverse Only Surviving': 
6413, 'Forward Only Surviving': 17315, 'Input Read Pairs': 2127436}


Remember that dicts are unordered. All the data is there, but in 
arbitrary order. Now that you have a nice function to extract the data, 
you can apply it to the lines of a data file in a simple loop:

with open("255.trim.log") as p:
    for line in p:
        if line.startswith("Input "):
            d = extract(line)
            print(d)  # or process it somehow



-- 
Steven

From jenh1536 at gmail.com  Tue Apr 14 03:39:36 2015
From: jenh1536 at gmail.com (Janelle Harb)
Date: Mon, 13 Apr 2015 21:39:36 -0400
Subject: [Tutor] Python Help
Message-ID: <C2926718-2D65-4892-AE02-282BF7C9FFD5@gmail.com>

Hello! I have a Mac and idle refuses to quit no matter what I try to do.  What should I do?
Thank you!
-Janelle

From alan.gauld at btinternet.com  Tue Apr 14 09:58:19 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 14 Apr 2015 08:58:19 +0100
Subject: [Tutor] Python Help
In-Reply-To: <C2926718-2D65-4892-AE02-282BF7C9FFD5@gmail.com>
References: <C2926718-2D65-4892-AE02-282BF7C9FFD5@gmail.com>
Message-ID: <mgihaq$chd$1@ger.gmane.org>

On 14/04/15 02:39, Janelle Harb wrote:
> Hello! I have a Mac and idle refuses to quit no matter what I try to do.  What should I do?

You  can start by giving us some specific examples of things you did 
that didn't work.

Starting with the obvious:
1) Did you click the little close icon?
2) Did you use the Quit option in the menus?
3) Did you try a Force Quit?
4) Did you run kill from the terminal?
5) Did you try rebooting?
6) Did you hit it with a club hammer?

Without any idea of what you did we can't suggest anything
specific. It might also help if you tell us which OS version,
which Python version, and whether this has always been
the case or if its something that only happened recently.
If the latter, what were you doing with IDLE immediately
before the problem arose?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From __peter__ at web.de  Tue Apr 14 10:00:47 2015
From: __peter__ at web.de (Peter Otten)
Date: Tue, 14 Apr 2015 10:00:47 +0200
Subject: [Tutor] Regular expression on python
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
 <20150414014816.GC5663@ando.pearwood.info>
Message-ID: <mgihfg$ep4$1@ger.gmane.org>

Steven D'Aprano wrote:

> On Mon, Apr 13, 2015 at 02:29:07PM +0200, jarod_v6 at libero.it wrote:
>> Dear all.
>> I would like to extract from some file some data.
>> The line I'm interested is this:
>> 
>> Input Read Pairs: 2127436 Both Surviving: 1795091 (84.38%) Forward
>> Only Surviving: 17315 (0.81%) Reverse Only Surviving: 6413 (0.30%)
>> Dropped: 308617 (14.51%)
> 
> 
>     Some people, when confronted with a problem, think "I know, I'll
>     use regular expressions." Now they have two problems.
>     -- Jamie Zawinski
> ?
> I swear that Perl has been a blight on an entire generation of
> programmers. All they know is regular expressions, so they turn every
> data processing problem into a regular expression. Or at least they
> *try* to. As you have learned, regular expressions are hard to read,
> hard to write, and hard to get correct.
> 
> Let's write some Python code instead.
> 
> 
> def extract(line):
>     # Extract key:number values from the string.
>     line = line.strip()  # Remove leading and trailing whitespace.
>     words = line.split()
>     accumulator = []  # Collect parts of the string we care about.
>     for word in words:
>         if word.startswith('(') and word.endswith('%)'):
>             # We don't care about percentages in brackets.
>             continue
>         try:
>             n = int(word)
>         except ValueError:
>             accumulator.append(word)
>         else:
>             accumulator.append(n)
>     # Now accumulator will be a list of strings and ints:
>     # e.g. ['Input', 'Read', 'Pairs:', 1234, 'Both', 'Surviving:', 1000]
>     # Collect consecutive strings as the key, int to be the value.
>     results = {}
>     keyparts = []
>     for item in accumulator:
>         if isinstance(item, int):
>             key = ' '.join(keyparts)
>             keyparts = []
>             if key.endswith(':'):
>                 key = key[:-1]
>             results[key] = item
>         else:
>             keyparts.append(item)
>     # When we have finished processing, the keyparts list should be empty.
>     if keyparts:
>         extra = ' '.join(keyparts)
>         print('Warning: found extra text at end of line "%s".' % extra)
>     return results
> 
> 
> 
> Now let me test it:
> 
> py> line = ('Input Read Pairs: 2127436 Both Surviving: 1795091'
> ...         ' (84.38%) Forward Only Surviving: 17315 (0.81%)'
> ...         ' Reverse Only Surviving: 6413 (0.30%) Dropped:'
> ...         ' 308617 (14.51%)\n')
> py>
> py> print(line)
> Input Read Pairs: 2127436 Both Surviving: 1795091 (84.38%) Forward
> Only Surviving: 17315 (0.81%) Reverse Only Surviving: 6413 (0.30%)
> Dropped: 308617 (14.51%)
> 
> py> extract(line)
> {'Dropped': 308617, 'Both Surviving': 1795091, 'Reverse Only Surviving':
> 6413, 'Forward Only Surviving': 17315, 'Input Read Pairs': 2127436}
> 
> 
> Remember that dicts are unordered. All the data is there, but in
> arbitrary order. Now that you have a nice function to extract the data,
> you can apply it to the lines of a data file in a simple loop:
> 
> with open("255.trim.log") as p:
>     for line in p:
>         if line.startswith("Input "):
>             d = extract(line)
>             print(d)  # or process it somehow

The tempter took posession of me and dictated:

>>> pprint.pprint(
... [(k, int(v)) for k, v in
... re.compile(r"(.+?):\s+(\d+)(?:\s+\(.*?\))?\s*").findall(line)])
[('Input Read Pairs', 2127436),
 ('Both Surviving', 1795091),
 ('Forward Only Surviving', 17315),
 ('Reverse Only Surviving', 6413),
 ('Dropped', 308617)]



From steve at pearwood.info  Tue Apr 14 14:21:25 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Tue, 14 Apr 2015 22:21:25 +1000
Subject: [Tutor] Regular expression on python
In-Reply-To: <mgihfg$ep4$1@ger.gmane.org>
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
 <20150414014816.GC5663@ando.pearwood.info> <mgihfg$ep4$1@ger.gmane.org>
Message-ID: <20150414122124.GE5663@ando.pearwood.info>

On Tue, Apr 14, 2015 at 10:00:47AM +0200, Peter Otten wrote:
> Steven D'Aprano wrote:

> > I swear that Perl has been a blight on an entire generation of
> > programmers. All they know is regular expressions, so they turn every
> > data processing problem into a regular expression. Or at least they
> > *try* to. As you have learned, regular expressions are hard to read,
> > hard to write, and hard to get correct.
> > 
> > Let's write some Python code instead.
[...]

> The tempter took posession of me and dictated:
> 
> >>> pprint.pprint(
> ... [(k, int(v)) for k, v in
> ... re.compile(r"(.+?):\s+(\d+)(?:\s+\(.*?\))?\s*").findall(line)])
> [('Input Read Pairs', 2127436),
>  ('Both Surviving', 1795091),
>  ('Forward Only Surviving', 17315),
>  ('Reverse Only Surviving', 6413),
>  ('Dropped', 308617)]

Nicely done :-)

I didn't say that it *couldn't* be done with a regex. Only that it is 
harder to read, write, etc. Regexes are good tools, but they aren't the 
only tool and as a beginner, which would you rather debug? The extract() 
function I wrote, or r"(.+?):\s+(\d+)(?:\s+\(.*?\))?\s*" ?

Oh, and for the record, your solution is roughly 4-5 times faster than 
the extract() function on my computer. If I knew the requirements were 
not likely to change (that is, the maintenance burden was likely to be 
low), I'd be quite happy to use your regex solution in production code, 
although I would probably want to write it out in verbose mode just in 
case the requirements did change:


r"""(?x)    (?# verbose mode)
    (.+?):  (?# capture one or more character, followed by a colon)
    \s+     (?# one or more whitespace)
    (\d+)   (?# capture one or more digits)
    (?:     (?# don't capture ... )
      \s+       (?# one or more whitespace)
      \(.*?\)   (?# anything inside round brackets)
      )?        (?# ... and optional)
    \s*     (?# ignore trailing spaces)
    """


That's a hint to people learning regular expressions: start in verbose 
mode, then "de-verbose" it if you must.


-- 
Steve

From __peter__ at web.de  Tue Apr 14 16:37:14 2015
From: __peter__ at web.de (Peter Otten)
Date: Tue, 14 Apr 2015 16:37:14 +0200
Subject: [Tutor] Regular expression on python
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
 <20150414014816.GC5663@ando.pearwood.info> <mgihfg$ep4$1@ger.gmane.org>
 <20150414122124.GE5663@ando.pearwood.info>
Message-ID: <mgj8mr$ls$1@ger.gmane.org>

Steven D'Aprano wrote:

> On Tue, Apr 14, 2015 at 10:00:47AM +0200, Peter Otten wrote:
>> Steven D'Aprano wrote:
> 
>> > I swear that Perl has been a blight on an entire generation of
>> > programmers. All they know is regular expressions, so they turn every
>> > data processing problem into a regular expression. Or at least they
>> > *try* to. As you have learned, regular expressions are hard to read,
>> > hard to write, and hard to get correct.
>> > 
>> > Let's write some Python code instead.
> [...]
> 
>> The tempter took posession of me and dictated:
>> 
>> >>> pprint.pprint(
>> ... [(k, int(v)) for k, v in
>> ... re.compile(r"(.+?):\s+(\d+)(?:\s+\(.*?\))?\s*").findall(line)])
>> [('Input Read Pairs', 2127436),
>>  ('Both Surviving', 1795091),
>>  ('Forward Only Surviving', 17315),
>>  ('Reverse Only Surviving', 6413),
>>  ('Dropped', 308617)]
> 
> Nicely done :-)
> 
> I didn't say that it *couldn't* be done with a regex. 

I didn't claim that.

> Only that it is
> harder to read, write, etc. Regexes are good tools, but they aren't the
> only tool and as a beginner, which would you rather debug? The extract()
> function I wrote, or r"(.+?):\s+(\d+)(?:\s+\(.*?\))?\s*" ?

I know a rhetorical question when I see one ;)

> Oh, and for the record, your solution is roughly 4-5 times faster than
> the extract() function on my computer. 

I wouldn't be bothered by that. See below if you are.

> If I knew the requirements were
> not likely to change (that is, the maintenance burden was likely to be
> low), I'd be quite happy to use your regex solution in production code,
> although I would probably want to write it out in verbose mode just in
> case the requirements did change:
> 
> 
> r"""(?x)    (?# verbose mode)
>     (.+?):  (?# capture one or more character, followed by a colon)
>     \s+     (?# one or more whitespace)
>     (\d+)   (?# capture one or more digits)
>     (?:     (?# don't capture ... )
>       \s+       (?# one or more whitespace)
>       \(.*?\)   (?# anything inside round brackets)
>       )?        (?# ... and optional)
>     \s*     (?# ignore trailing spaces)
>     """
> 
> 
> That's a hint to people learning regular expressions: start in verbose
> mode, then "de-verbose" it if you must.

Regarding the speed of the Python approach: you can easily improve that by 
relatively minor modifications. The most important one is to avoid the 
exception:

$ python parse_jarod.py
$ python3 parse_jarod.py

The regex for reference:

$ python3 -m timeit -s "from parse_jarod import extract_re as extract" 
"extract()"
100000 loops, best of 3: 18.6 usec per loop

Steven's original extract():

$ python3 -m timeit -s "from parse_jarod import extract_daprano as extract" 
"extract()"
10000 loops, best of 3: 92.6 usec per loop

Avoid raising ValueError (This won't work with negative numbers):

$ python3 -m timeit -s "from parse_jarod import extract_daprano2 as extract" 
"extract()"
10000 loops, best of 3: 44.3 usec per loop

Collapse the two loops into one, thus avoiding the accumulator list and the 
isinstance() checks:

$ python3 -m timeit -s "from parse_jarod import extract_daprano3 as extract" 
"extract()"
10000 loops, best of 3: 29.6 usec per loop

Ok, this is still slower than the regex, a result that I cannot accept. 
Let's try again:

$ python3 -m timeit -s "from parse_jarod import extract_py as extract" 
"extract()"
100000 loops, best of 3: 15.1 usec per loop

Heureka? The "winning" code is brittle and probably as hard to understand as 
the regex. You can judge for yourself if you're interested:

$ cat parse_jarod.py                       
import re

line = ("Input Read Pairs: 2127436 "
        "Both Surviving: 1795091 (84.38%) "
        "Forward Only Surviving: 17315 (0.81%) "
        "Reverse Only Surviving: 6413 (0.30%) "
        "Dropped: 308617 (14.51%)")
_findall = re.compile(r"(.+?):\s+(\d+)(?:\s+\(.*?\))?\s*").findall


def extract_daprano(line=line):
    # Extract key:number values from the string.
    line = line.strip()  # Remove leading and trailing whitespace.
    words = line.split()
    accumulator = []  # Collect parts of the string we care about.
    for word in words:
        if word.startswith('(') and word.endswith('%)'):
            # We don't care about percentages in brackets.
            continue
        try:
            n = int(word)
        except ValueError:
            accumulator.append(word)
        else:
            accumulator.append(n)
    # Now accumulator will be a list of strings and ints:
    # e.g. ['Input', 'Read', 'Pairs:', 1234, 'Both', 'Surviving:', 1000]
    # Collect consecutive strings as the key, int to be the value.
    results = {}
    keyparts = []
    for item in accumulator:
        if isinstance(item, int):
            key = ' '.join(keyparts)
            keyparts = []
            if key.endswith(':'):
                key = key[:-1]
            results[key] = item
        else:
            keyparts.append(item)
    # When we have finished processing, the keyparts list should be empty.
    if keyparts:
        extra = ' '.join(keyparts)
        print('Warning: found extra text at end of line "%s".' % extra)
    return results


def extract_daprano2(line=line):
    words = line.split()
    accumulator = []
    for word in words:
        if word.startswith('(') and word.endswith('%)'):
            continue
        if word.isdigit():
            word = int(word)
        accumulator.append(word)

    results = {}
    keyparts = []
    for item in accumulator:
        if isinstance(item, int):
            key = ' '.join(keyparts)
            keyparts = []
            if key.endswith(':'):
                key = key[:-1]
            results[key] = item
        else:
            keyparts.append(item)
    # When we have finished processing, the keyparts list should be empty.
    if keyparts:
        extra = ' '.join(keyparts)
        print('Warning: found extra text at end of line "%s".' % extra)
    return results


def extract_daprano3(line=line):
    results = {}
    keyparts = []
    for word in line.split():
        if word.startswith("("):
            continue
        if word.isdigit():
            key = ' '.join(keyparts)
            keyparts = []
            if key.endswith(':'):
                key = key[:-1]
            results[key] = int(word)
        else:
            keyparts.append(word)

    # When we have finished processing, the keyparts list should be empty.
    if keyparts:
        extra = ' '.join(keyparts)
        print('Warning: found extra text at end of line "%s".' % extra)
    return results


def extract_re(line=line):
    return {k: int(v) for k, v in _findall(line)}


def extract_py(line=line):
    key = None
    result = {}
    for part in line.split(":"):
        if key is None:
            key = part
        else:
            value, new_key = part.split(None, 1)
            result[key] = int(value)
            key = new_key.rpartition(")")[-1].strip()
    return result


if __name__ == "__main__":
    assert (extract_daprano() == extract_re() == extract_daprano2()
            == extract_daprano3() == extract_py())



From cybervigilante at gmail.com  Tue Apr 14 18:56:32 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Tue, 14 Apr 2015 09:56:32 -0700
Subject: [Tutor] where is the wsgi server root?
Message-ID: <CALRAYNXqVq-WWy78XEv2=B6wSJqWz071BshF8Uzt-fqapQSu4g@mail.gmail.com>

I set up a simple python wsgi server on port 8000,  which works, but where
the heck is the server root? Is there a physical server root I can simply
put a python program in, as I put a html program into the wampserver root,
and see it in a browser on localhost:port 8000, or do I need to do a bit
more reading ;')   I just cut and pasted the server setup code from the
docs, and assumed a server would have a physical root as my local
wampserver does. I don't want to fool with django right now - just do the
simplest thing to see if I can get python on a web page since I'm used to
making them.

Or if the root is virtual how do I set up a physical root?

Or am I totally confused?

-- 
Jim

From alan.gauld at btinternet.com  Wed Apr 15 01:09:09 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 15 Apr 2015 00:09:09 +0100
Subject: [Tutor] where is the wsgi server root?
In-Reply-To: <CALRAYNXqVq-WWy78XEv2=B6wSJqWz071BshF8Uzt-fqapQSu4g@mail.gmail.com>
References: <CALRAYNXqVq-WWy78XEv2=B6wSJqWz071BshF8Uzt-fqapQSu4g@mail.gmail.com>
Message-ID: <mgk6mk$biq$1@ger.gmane.org>

On 14/04/15 17:56, Jim Mooney wrote:

> simplest thing to see if I can get python on a web page since I'm used to
> making them.
>
> Or if the root is virtual how do I set up a physical root?

I'm guessing; but I'd expect it to be the current directory
when you started the server. try adding a

print( os,getcwd() )

And see if the result is your root.
Or you could try reading the documents...they might tell you!

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From joel.goldstick at gmail.com  Wed Apr 15 01:23:47 2015
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Tue, 14 Apr 2015 19:23:47 -0400
Subject: [Tutor] where is the wsgi server root?
In-Reply-To: <CALRAYNXqVq-WWy78XEv2=B6wSJqWz071BshF8Uzt-fqapQSu4g@mail.gmail.com>
References: <CALRAYNXqVq-WWy78XEv2=B6wSJqWz071BshF8Uzt-fqapQSu4g@mail.gmail.com>
Message-ID: <CAPM-O+yKb-qzLg=t8z-VC=f9GK+D+8LfvjgncGVdOZRWkbspoQ@mail.gmail.com>

On Tue, Apr 14, 2015 at 12:56 PM, Jim Mooney <cybervigilante at gmail.com> wrote:
> I set up a simple python wsgi server on port 8000,  which works, but where
> the heck is the server root? Is there a physical server root I can simply
> put a python program in, as I put a html program into the wampserver root,
> and see it in a browser on localhost:port 8000, or do I need to do a bit
> more reading ;')   I just cut and pasted the server setup code from the
> docs, and assumed a server would have a physical root as my local
> wampserver does. I don't want to fool with django right now - just do the
> simplest thing to see if I can get python on a web page since I'm used to
> making them.
>
> Or if the root is virtual how do I set up a physical root?
>
> Or am I totally confused?
>
> --
> Jim

Here is a link about wsgi:
https://code.google.com/p/modwsgi/

It isn't like php.  You can put your code anywhere.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Joel Goldstick
http://joelgoldstick.com

From alan.gauld at btinternet.com  Wed Apr 15 01:49:26 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 15 Apr 2015 00:49:26 +0100
Subject: [Tutor] Regular expression on python
In-Reply-To: <20150414122124.GE5663@ando.pearwood.info>
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
 <20150414014816.GC5663@ando.pearwood.info> <mgihfg$ep4$1@ger.gmane.org>
 <20150414122124.GE5663@ando.pearwood.info>
Message-ID: <mgk925$f6p$1@ger.gmane.org>

On 14/04/15 13:21, Steven D'Aprano wrote:

> although I would probably want to write it out in verbose mode just in
> case the requirements did change:
>
>
> r"""(?x)    (?# verbose mode)
>      (.+?):  (?# capture one or more character, followed by a colon)
>      \s+     (?# one or more whitespace)
>      (\d+)   (?# capture one or more digits)
>      (?:     (?# don't capture ... )
>        \s+       (?# one or more whitespace)
>        \(.*?\)   (?# anything inside round brackets)
>        )?        (?# ... and optional)
>      \s*     (?# ignore trailing spaces)
>      """
>
> That's a hint to people learning regular expressions: start in verbose
> mode, then "de-verbose" it if you must.

New one on me. Where does one find out about verbose mode?
I don't see it in the re docs?

I see an re.X flag but while it seems to be similar in purpose
yet it is different to your style above (no parens for example)?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From breamoreboy at yahoo.co.uk  Wed Apr 15 01:59:43 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 15 Apr 2015 00:59:43 +0100
Subject: [Tutor] Regular expression on python
In-Reply-To: <mgk925$f6p$1@ger.gmane.org>
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
 <20150414014816.GC5663@ando.pearwood.info> <mgihfg$ep4$1@ger.gmane.org>
 <20150414122124.GE5663@ando.pearwood.info> <mgk925$f6p$1@ger.gmane.org>
Message-ID: <mgk9lj$o3l$1@ger.gmane.org>

On 15/04/2015 00:49, Alan Gauld wrote:
> On 14/04/15 13:21, Steven D'Aprano wrote:
>
>> although I would probably want to write it out in verbose mode just in
>> case the requirements did change:
>>
>>
>> r"""(?x)    (?# verbose mode)
>>      (.+?):  (?# capture one or more character, followed by a colon)
>>      \s+     (?# one or more whitespace)
>>      (\d+)   (?# capture one or more digits)
>>      (?:     (?# don't capture ... )
>>        \s+       (?# one or more whitespace)
>>        \(.*?\)   (?# anything inside round brackets)
>>        )?        (?# ... and optional)
>>      \s*     (?# ignore trailing spaces)
>>      """
>>
>> That's a hint to people learning regular expressions: start in verbose
>> mode, then "de-verbose" it if you must.
>
> New one on me. Where does one find out about verbose mode?
> I don't see it in the re docs?
>
> I see an re.X flag but while it seems to be similar in purpose
> yet it is different to your style above (no parens for example)?
>

https://docs.python.org/3/library/re.html#module-contents re.X and 
re.VERBOSE are together.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From steve at pearwood.info  Wed Apr 15 03:02:59 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 15 Apr 2015 11:02:59 +1000
Subject: [Tutor] Regular expression on python
In-Reply-To: <mgk925$f6p$1@ger.gmane.org>
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
 <20150414014816.GC5663@ando.pearwood.info> <mgihfg$ep4$1@ger.gmane.org>
 <20150414122124.GE5663@ando.pearwood.info> <mgk925$f6p$1@ger.gmane.org>
Message-ID: <20150415010259.GH5663@ando.pearwood.info>

On Wed, Apr 15, 2015 at 12:49:26AM +0100, Alan Gauld wrote:

> New one on me. Where does one find out about verbose mode?
> I don't see it in the re docs?
> 
> I see an re.X flag but while it seems to be similar in purpose
> yet it is different to your style above (no parens for example)?

I presume it is documented in the main docs, but I actually found this 
in the "Python Pocket Reference" by Mark Lutz :-)

All of the regex flags have three forms:

- a numeric flag with a long name;
- the same numeric flag with a short name;
- a regular expression pattern.

So you can either do:

re.compile(pattern, flags)

or embed the flag in the pattern. The flags that I know of are:

(?i) re.I re.IGNORECASE
(?L) re.L re.LOCALE
(?M) re.M re.MULTILINE
(?s) re.S re.DOTALL
(?x) re.X re.VERBOSE

The flag can appear anywhere in the pattern and applies to the whole 
pattern, but it is good practice to put them at the front, and in the 
future it may be an error to put the flags elsewhere.

When provided as a separate argument, you can combine flags like this:

re.I|re.X


-- 
Steve

From akleider at sonic.net  Wed Apr 15 07:58:18 2015
From: akleider at sonic.net (Alex Kleider)
Date: Tue, 14 Apr 2015 22:58:18 -0700
Subject: [Tutor] Regular expression on python
In-Reply-To: <mgk925$f6p$1@ger.gmane.org>
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
 <20150414014816.GC5663@ando.pearwood.info> <mgihfg$ep4$1@ger.gmane.org>
 <20150414122124.GE5663@ando.pearwood.info> <mgk925$f6p$1@ger.gmane.org>
Message-ID: <ebfd8639517d0c050b43ea20e1a62834@sonic.net>

On 2015-04-14 16:49, Alan Gauld wrote:

> New one on me. Where does one find out about verbose mode?
> I don't see it in the re docs?

This is where I go whenever I find myself having to (re)learn the 
details of regex:
https://docs.python.org/3/howto/regex.html

I believe a '2' can be substituted for the '3' but I've not found any 
difference between the two.

(I submit this not so much for Alan (tutor) as for those like me who are 
learning.)


From cybervigilante at gmail.com  Wed Apr 15 05:11:41 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Tue, 14 Apr 2015 20:11:41 -0700
Subject: [Tutor] where is the wsgi server root?
In-Reply-To: <mgk6mk$biq$1@ger.gmane.org>
References: <CALRAYNXqVq-WWy78XEv2=B6wSJqWz071BshF8Uzt-fqapQSu4g@mail.gmail.com>
 <mgk6mk$biq$1@ger.gmane.org>
Message-ID: <CALRAYNV4xye3eR6GM2M91dq9WHJdDOeyHLy22r_0mxbKHk3L5Q@mail.gmail.com>

I'm guessing; but I'd expect it to be the current directory

> when you started the server. try adding a
>
> print( os,getcwd() )
>
> And see if the result is your root.
> Or you could try reading the documents...they might tell you!
>
> --
> Alan G


Read the docs? Where's the fun in that ;')

Actually, I found the root in the curdir and got a simple index.html page
going on the python server at port 8000. Odd, I figured it would be
index.py, as in index.php. That's all I wanted to do at present - see if I
could get it working.

Jim

From alan.gauld at btinternet.com  Wed Apr 15 09:19:04 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 15 Apr 2015 08:19:04 +0100
Subject: [Tutor] Regular expression on python
In-Reply-To: <20150415010259.GH5663@ando.pearwood.info>
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
 <20150414014816.GC5663@ando.pearwood.info> <mgihfg$ep4$1@ger.gmane.org>
 <20150414122124.GE5663@ando.pearwood.info> <mgk925$f6p$1@ger.gmane.org>
 <20150415010259.GH5663@ando.pearwood.info>
Message-ID: <mgl3d6$mj2$1@ger.gmane.org>

On 15/04/15 02:02, Steven D'Aprano wrote:
>> New one on me. Where does one find out about verbose mode?
>> I don't see it in the re docs?
>>

> or embed the flag in the pattern. The flags that I know of are:
>
> (?x) re.X re.VERBOSE
>
> The flag can appear anywhere in the pattern and applies to the whole
> pattern, but it is good practice to put them at the front, and in the
> future it may be an error to put the flags elsewhere.

I've always applied flags as separate params at the end of the
function call. I've never seen (or noticed?) the embedded form,
and don't see it described in the docs anywhere (although it
probably is). But the re module descriptions of the flags only goive the 
re.X/re.VERBOSE options, no mention of the embedded form.
Maybe you are just supposed to infer the (?x) form from the re.X...

However, that still doesn't explain the difference in your comment
syntax.

The docs say the verbose syntax looks like:

a = re.compile(r"""\d +  # the integral part
                    \.    # the decimal point
                    \d *  # some fractional digits""", re.X)

Whereas your syntax is like:

a = re.compile(r"""(?x)  (?# turn on verbose mode)
                    \d +  (?# the integral part)
                    \.    (?# the decimal point)
                    \d *  (?# some fractional digits)""")

Again, where is that described?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From __peter__ at web.de  Wed Apr 15 10:24:59 2015
From: __peter__ at web.de (Peter Otten)
Date: Wed, 15 Apr 2015 10:24:59 +0200
Subject: [Tutor] Regular expression on python
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
 <20150414014816.GC5663@ando.pearwood.info> <mgihfg$ep4$1@ger.gmane.org>
 <20150414122124.GE5663@ando.pearwood.info> <mgk925$f6p$1@ger.gmane.org>
 <20150415010259.GH5663@ando.pearwood.info> <mgl3d6$mj2$1@ger.gmane.org>
Message-ID: <mgl78s$g4a$1@ger.gmane.org>

Alan Gauld wrote:

> On 15/04/15 02:02, Steven D'Aprano wrote:
>>> New one on me. Where does one find out about verbose mode?
>>> I don't see it in the re docs?
>>>
> 
>> or embed the flag in the pattern. The flags that I know of are:
>>
>> (?x) re.X re.VERBOSE
>>
>> The flag can appear anywhere in the pattern and applies to the whole
>> pattern, but it is good practice to put them at the front, and in the
>> future it may be an error to put the flags elsewhere.
> 
> I've always applied flags as separate params at the end of the
> function call. I've never seen (or noticed?) the embedded form,
> and don't see it described in the docs anywhere (although it
> probably is). 

Quoting <https://docs.python.org/dev/library/re.html>:

"""
(?aiLmsux)
(One or more letters from the set 'a', 'i', 'L', 'm', 's', 'u', 'x'.) The 
group matches the empty string; the letters set the corresponding flags: 
re.A (ASCII-only matching), re.I (ignore case), re.L (locale dependent), 
re.M (multi-line), re.S (dot matches all), and re.X (verbose), for the 
entire regular expression. (The flags are described in Module Contents.) 
This is useful if you wish to include the flags as part of the regular 
expression, instead of passing a flag argument to the re.compile() function.

Note that the (?x) flag changes how the expression is parsed. It should be 
used first in the expression string, or after one or more whitespace 
characters. If there are non-whitespace characters before the flag, the 
results are undefined.
"""

> But the re module descriptions of the flags only goive the
> re.X/re.VERBOSE options, no mention of the embedded form.
> Maybe you are just supposed to infer the (?x) form from the re.X...
> 
> However, that still doesn't explain the difference in your comment
> syntax.
> 
> The docs say the verbose syntax looks like:
> 
> a = re.compile(r"""\d +  # the integral part
>                     \.    # the decimal point
>                     \d *  # some fractional digits""", re.X)
> 
> Whereas your syntax is like:
> 
> a = re.compile(r"""(?x)  (?# turn on verbose mode)
>                     \d +  (?# the integral part)
>                     \.    (?# the decimal point)
>                     \d *  (?# some fractional digits)""")
> 
> Again, where is that described?

"""
(?#...)
A comment; the contents of the parentheses are simply ignored.
"""

Let's try it out:

>>> re.compile("\d+(?# sequence of digits)").findall("alpha 123 beta 456")
['123', '456']
>>> re.compile("\d+# sequence of digits").findall("alpha 123 beta 456")
[]
>>> re.compile("\d+# sequence of digits", re.VERBOSE).findall("alpha 123 
beta 456")
['123', '456']

So (?#...)-style comments work in non-verbose mode, too, and Steven is 
wearing belt and braces (almost, the verbose flag is still necessary to 
ignore the extra whitespace).


From fomcl at yahoo.com  Wed Apr 15 10:50:04 2015
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Wed, 15 Apr 2015 01:50:04 -0700
Subject: [Tutor] Regular expression on python
In-Reply-To: <mgj8mr$ls$1@ger.gmane.org>
Message-ID: <1429087804.16005.YahooMailBasic@web163804.mail.gq1.yahoo.com>

--------------------------------------------
On Tue, 4/14/15, Peter Otten <__peter__ at web.de> wrote:

 Subject: Re: [Tutor] Regular expression on python
 To: tutor at python.org
 Date: Tuesday, April 14, 2015, 4:37 PM
 
 Steven D'Aprano wrote:
 
 > On Tue, Apr 14, 2015 at 10:00:47AM +0200, Peter Otten
 wrote:
 >> Steven D'Aprano wrote:
 > 
 >> > I swear that Perl has been a blight on an
 entire generation of
 >> > programmers. All they know is regular
 expressions, so they turn every
 >> > data processing problem into a regular
 expression. Or at least they
 >> > *try* to. As you have learned, regular
 expressions are hard to read,
 >> > hard to write, and hard to get correct.
 >> > 
 >> > Let's write some Python code instead.
 > [...]
 > 
 >> The tempter took posession of me and dictated:
 >> 
 >> >>> pprint.pprint(
 >> ... [(k, int(v)) for k, v in
 >> ...
 re.compile(r"(.+?):\s+(\d+)(?:\s+\(.*?\))?\s*").findall(line)])
 >> [('Input Read Pairs', 2127436),
 >>? ('Both Surviving', 1795091),
 >>? ('Forward Only Surviving', 17315),
 >>? ('Reverse Only Surviving', 6413),
 >>? ('Dropped', 308617)]
 > 
 > Nicely done :-)
 > 


Yes, nice, but why do you use 
re.compile(regex).findall(line) 
and not
re.findall(regex, line)

I know what re.compile is for. I often use it outside a loop and then actually use the compiled regex inside a loop, I just haven't see the way you use it before.



 > I didn't say that it *couldn't* be done with a regex. 
 
 I didn't claim that.
 
 > Only that it is
 > harder to read, write, etc. Regexes are good tools, but
 they aren't the
 > only tool and as a beginner, which would you rather
 debug? The extract()
 > function I wrote, or
 r"(.+?):\s+(\d+)(?:\s+\(.*?\))?\s*" ?
 
 I know a rhetorical question when I see one ;)
 
 > Oh, and for the record, your solution is roughly 4-5
 times faster than
 > the extract() function on my computer. 
 
 I wouldn't be bothered by that. See below if you are.
 
 > If I knew the requirements were
 > not likely to change (that is, the maintenance burden
 was likely to be
 > low), I'd be quite happy to use your regex solution in
 production code,
 > although I would probably want to write it out in
 verbose mode just in
 > case the requirements did change:
 > 
 > 
 > r"""(?x)? ? (?# verbose mode)

personally, I prefer to be verbose about being verbose, ie use the re.VERBOSE flag. But perhaps that's just a matter of taste. Are there any use cases when the ?iLmsux operators are clearly a better choice than the equivalent flag? For me, the mental burden of a regex is big enough already without these operators. 


 >? ???(.+?):? (?# capture one or
 more character, followed by a colon)
 >? ???\s+? ???(?#
 one or more whitespace)
 >? ???(\d+)???(?#
 capture one or more digits)
 >? ???(?:? ???(?#
 don't capture ... )
 >? ? ???\s+? ?
 ???(?# one or more whitespace)
 >? ?
 ???\(.*?\)???(?# anything
 inside round brackets)
 >? ? ???)?? ? ?
 ? (?# ... and optional)
 >? ???\s*? ???(?#
 ignore trailing spaces)
 >? ???"""

<snip>

From __peter__ at web.de  Wed Apr 15 11:42:34 2015
From: __peter__ at web.de (Peter Otten)
Date: Wed, 15 Apr 2015 11:42:34 +0200
Subject: [Tutor] Regular expression on python
References: <mgj8mr$ls$1@ger.gmane.org>
 <1429087804.16005.YahooMailBasic@web163804.mail.gq1.yahoo.com>
Message-ID: <mglbqc$178$1@ger.gmane.org>

Albert-Jan Roskam wrote:

> On Tue, 4/14/15, Peter Otten <__peter__ at web.de> wrote:

>>> >>> pprint.pprint(
>>> ... [(k, int(v)) for k, v in
>>> ...
>re.compile(r"(.+?):\s+(\d+)(?:\s+\(.*?\))?\s*").findall(line)])
>>> [('Input Read Pairs', 2127436),
>>>('Both Surviving', 1795091),
>>>('Forward Only Surviving', 17315),
>>>('Reverse Only Surviving', 6413),
>>>('Dropped', 308617)]

> Yes, nice, but why do you use
> re.compile(regex).findall(line)
> and not
> re.findall(regex, line)
> 
> I know what re.compile is for. I often use it outside a loop and then
> actually use the compiled regex inside a loop, I just haven't see the way
> you use it before.

What you describe here is how I use regular expressions most of the time.
Also, re.compile() behaves the same over different Python versions while the 
shortcuts for the pattern methods changed signature over time. 
Finally, some have a gotcha. Compare:

>>> re.compile("a", re.IGNORECASE).sub("b", "aAAaa")
'bbbbb'
>>> re.sub("a", "b", "aAAaa", re.IGNORECASE)
'bAAba'

Did you expect that? Congrats for thorough reading of the docs ;)

> personally, I prefer to be verbose about being verbose, ie use the
> re.VERBOSE flag. But perhaps that's just a matter of taste. Are there any
> use cases when the ?iLmsux operators are clearly a better choice than the
> equivalent flag? For me, the mental burden of a regex is big enough
> already without these operators. 

I pass flags separately myself, but

>>> re.sub("(?i)a", "b", "aAAaa")
'bbbbb'

might serve as an argument for inlined flags.


From beachkidken at gmail.com  Wed Apr 15 14:21:33 2015
From: beachkidken at gmail.com (Ken G.)
Date: Wed, 15 Apr 2015 08:21:33 -0400
Subject: [Tutor] Changing a string number to another number
Message-ID: <552E57CD.60005@gmail.com>

When running the following code, I get the following
error code:

201504110102030405061
Traceback (most recent call last):
   File "Mega_Millions_Tickets_Change.py", line 11, in <module>
     datecode[20:21] = "0"
TypeError: 'str' object does not support item assignment


datecode = "201504110102030405061"
print datecode
if datecode[20:21] == "1":
     datecode[20:21] = "0"
print datecode


I have tried using the zero as an integer but still get the same error code.
Any suggestion?

Thanks in advance,

Ken

From davea at davea.name  Wed Apr 15 14:36:17 2015
From: davea at davea.name (Dave Angel)
Date: Wed, 15 Apr 2015 08:36:17 -0400
Subject: [Tutor] Changing a string number to another number
In-Reply-To: <552E57CD.60005@gmail.com>
References: <552E57CD.60005@gmail.com>
Message-ID: <552E5B41.8040009@davea.name>

On 04/15/2015 08:21 AM, Ken G. wrote:
> When running the following code, I get the following
> error code:
>
> 201504110102030405061
> Traceback (most recent call last):
>    File "Mega_Millions_Tickets_Change.py", line 11, in <module>
>      datecode[20:21] = "0"
> TypeError: 'str' object does not support item assignment

A 'str' object is immutable, which means simply that you cannot modify 
it in place.  All you can do is create a new str object, and rebind your 
variable to that new one.  That means that there are a number of things 
you cannot do directly to a string.  One of them is modifying a slice, 
as you're trying to do.

>
>
> datecode = "201504110102030405061"
> print datecode
> if datecode[20:21] == "1":
>      datecode[20:21] = "0"
> print datecode
>
>

I can see that the first part of this is probably a standard datetime, 
and might suggest you convert it to one, and modify that as needed.  But 
you're so far to the right that I have to figure you're doing some 
custom encoding.

If you just want to replace a single character of a string, you could 
use the construct:

datecode = datecode[:20] + "0" + datecode[21:]

If you need something fancier, perhaps you can generalize it.

-- 
DaveA

From __peter__ at web.de  Wed Apr 15 14:50:57 2015
From: __peter__ at web.de (Peter Otten)
Date: Wed, 15 Apr 2015 14:50:57 +0200
Subject: [Tutor] Changing a string number to another number
References: <552E57CD.60005@gmail.com>
Message-ID: <mglmrj$u64$1@ger.gmane.org>

Ken G. wrote:

> When running the following code, I get the following
> error code:
> 
> 201504110102030405061
> Traceback (most recent call last):
>    File "Mega_Millions_Tickets_Change.py", line 11, in <module>
>      datecode[20:21] = "0"
> TypeError: 'str' object does not support item assignment
> 
> 
> datecode = "201504110102030405061"
> print datecode
> if datecode[20:21] == "1":
>      datecode[20:21] = "0"
> print datecode
> 
> 
> I have tried using the zero as an integer but still get the same error
> code. Any suggestion?

Strings in Python are "immutable", i. e. you cannot change them once they 
are created. Instead you have to construct a new string. In the general case 
you can get the same effect as replacing the character #n of an all-ascii 
string with

>>> s = "01234567890"
>>> n = 3
>>> s[:n] + "x" + s[n+1:]
'012x4567890'

In your case you want to replace the last character, so s[n+1:] is empty

>>> s = "201504110102030405061"
>>> n = 20
>>> s[n+1:]
''

and just

>>> s[:n] + "x"
'20150411010203040506x'

is sufficient. A word of warning: as you are using Python 2 you are actually 
manipulating bytes not characters when using the default string type. This 
may have ugly consequences:

>>> s = "?hnlich" # I'm using UTF-8
>>> print "ae" + s[1:]
ae?hnlich

Here the new string is not valid UTF-8 because in that encoding a-umlaut 
consists of two bytes and I'm only removing one of them.

A partial fix is to use unicode explicitly:

>>> s = u"?hnlich"
>>> print "ae" + s[1:]
aehnlich

But if you are just starting consider switching to Python 3 where unicode is 
the default string type.


From beachkidken at gmail.com  Wed Apr 15 14:51:44 2015
From: beachkidken at gmail.com (Ken G.)
Date: Wed, 15 Apr 2015 08:51:44 -0400
Subject: [Tutor] Changing a string number to another number [RESOLVED]
In-Reply-To: <552E5B41.8040009@davea.name>
References: <552E57CD.60005@gmail.com> <552E5B41.8040009@davea.name>
Message-ID: <552E5EE0.1040702@gmail.com>



On 04/15/2015 08:36 AM, Dave Angel wrote:
> On 04/15/2015 08:21 AM, Ken G. wrote:
>> When running the following code, I get the following
>> error code:
>>
>> 201504110102030405061
>> Traceback (most recent call last):
>>    File "Mega_Millions_Tickets_Change.py", line 11, in <module>
>>      datecode[20:21] = "0"
>> TypeError: 'str' object does not support item assignment
>
> A 'str' object is immutable, which means simply that you cannot modify 
> it in place.  All you can do is create a new str object, and rebind 
> your variable to that new one.  That means that there are a number of 
> things you cannot do directly to a string.  One of them is modifying a 
> slice, as you're trying to do.
>
>>
>>
>> datecode = "201504110102030405061"
>> print datecode
>> if datecode[20:21] == "1":
>>      datecode[20:21] = "0"
>> print datecode
>>
>>
>
> I can see that the first part of this is probably a standard datetime, 
> and might suggest you convert it to one, and modify that as needed.  
> But you're so far to the right that I have to figure you're doing some 
> custom encoding.
>
> If you just want to replace a single character of a string, you could 
> use the construct:
>
> datecode = datecode[:20] + "0" + datecode[21:]
>
> If you need something fancier, perhaps you can generalize it.
>
Thank you, Dave. That did the trick. You were partly right about the
datetime as the first part is a date and following contains the lotto
numbers purchased for that date of a drawing. The last number in
the string indicates if a bonus multiplier for the ticket was purchased,
0 for no and 1 for yes.

Again, thanks.

Ken

From robertvstepp at gmail.com  Wed Apr 15 14:55:28 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 15 Apr 2015 07:55:28 -0500
Subject: [Tutor] How to get a Tkinter window to print a color copy of itself
	as a .pdf file?
Message-ID: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>

Solaris 10, Python 2.4.4

I have very little experience with issuing print commands using a Unix
environment. Despite this, I wish to design a Tkinter window with a
"Print" button, which, when clicked, would create a copy of the
contents of the window as a .pdf file. GhostScript is available on my
systems.

I know that the Canvas container has the ability to print itself to a
postscript file, but I do not want to use Canvas as my container
object. So I am hopeful this is as simple as discovering the proper
command to associate with a button, which will generate a color
postscript file of the containing window. Once I can get that file, I
know how to get a .pdf out of it.

The main software that we use on these systems has this print command
associated with its color printer *button*:

lp -c -d ricoh -o resolution=1200 -o profile=photo -o dithering=photo
-o colorsettings=superfine -o black=k -o papper=letter -o itray=tray1

BTW, "papper" is what is actually in this software product's color
printer settings. But can this be correct? Anyway, it does print to
*paper*!

I suspect that some variant of this command associated with a print
button would print *something*, but how do I get it to print the
specific window containing the to-be-designed print button? Also, I
need it to print a postscript file, not print to paper. I suspect this
is another configuration setting that I need to research.

As always, many thanks in advance!

-- 
boB

From steve at pearwood.info  Wed Apr 15 15:09:25 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 15 Apr 2015 23:09:25 +1000
Subject: [Tutor] Changing a string number to another number
In-Reply-To: <552E57CD.60005@gmail.com>
References: <552E57CD.60005@gmail.com>
Message-ID: <20150415130924.GI5663@ando.pearwood.info>

On Wed, Apr 15, 2015 at 08:21:33AM -0400, Ken G. wrote:
> When running the following code, I get the following
> error code:
> 
> 201504110102030405061
> Traceback (most recent call last):
>   File "Mega_Millions_Tickets_Change.py", line 11, in <module>
>     datecode[20:21] = "0"
> TypeError: 'str' object does not support item assignment

Try this:

datacode = datacode[:20] + "0" + datacode[21:]


This is called "slicing". We take a slice of the string, from the start 
up to just before position 20; "0"; and a slice from position 21 to the 
end of the string. The three pieces are then concatenated together, 
giving a new string.



-- 
Steve

From beachkidken at gmail.com  Wed Apr 15 15:15:46 2015
From: beachkidken at gmail.com (Ken G.)
Date: Wed, 15 Apr 2015 09:15:46 -0400
Subject: [Tutor] Changing a string number to another number [RESOLVED]
In-Reply-To: <mglmrj$u64$1@ger.gmane.org>
References: <552E57CD.60005@gmail.com> <mglmrj$u64$1@ger.gmane.org>
Message-ID: <552E6482.3040701@gmail.com>



On 04/15/2015 08:50 AM, Peter Otten wrote:
> Ken G. wrote:
>
>> When running the following code, I get the following
>> error code:
>>
>> 201504110102030405061
>> Traceback (most recent call last):
>>     File "Mega_Millions_Tickets_Change.py", line 11, in <module>
>>       datecode[20:21] = "0"
>> TypeError: 'str' object does not support item assignment
>>
>>
>> datecode = "201504110102030405061"
>> print datecode
>> if datecode[20:21] == "1":
>>       datecode[20:21] = "0"
>> print datecode
>>
>>
>> I have tried using the zero as an integer but still get the same error
>> code. Any suggestion?
> Strings in Python are "immutable", i. e. you cannot change them once they
> are created. Instead you have to construct a new string. In the general case
> you can get the same effect as replacing the character #n of an all-ascii
> string with
>
>>>> s = "01234567890"
>>>> n = 3
>>>> s[:n] + "x" + s[n+1:]
> '012x4567890'
>
> In your case you want to replace the last character, so s[n+1:] is empty
>
>>>> s = "201504110102030405061"
>>>> n = 20
>>>> s[n+1:]
> ''
>
> and just
>
>>>> s[:n] + "x"
> '20150411010203040506x'
>
> is sufficient. A word of warning: as you are using Python 2 you are actually
> manipulating bytes not characters when using the default string type. This
> may have ugly consequences:
>
>>>> s = "?hnlich" # I'm using UTF-8
>>>> print "ae" + s[1:]
> ae?hnlich
>
> Here the new string is not valid UTF-8 because in that encoding a-umlaut
> consists of two bytes and I'm only removing one of them.
>
> A partial fix is to use unicode explicitly:
>
>>>> s = u"?hnlich"
>>>> print "ae" + s[1:]
> aehnlich
>
> But if you are just starting consider switching to Python 3 where unicode is
> the default string type.
>
Thank you, Peter. That would be something for me to consider.
Alas, I am still using Python 2.7.6 but do have it on standby.

Again, thanks.

Ken

From beachkidken at gmail.com  Wed Apr 15 15:18:59 2015
From: beachkidken at gmail.com (Ken G.)
Date: Wed, 15 Apr 2015 09:18:59 -0400
Subject: [Tutor] Changing a string number to another number [RESOLVED]
In-Reply-To: <20150415130924.GI5663@ando.pearwood.info>
References: <552E57CD.60005@gmail.com>
 <20150415130924.GI5663@ando.pearwood.info>
Message-ID: <552E6543.2040706@gmail.com>



On 04/15/2015 09:09 AM, Steven D'Aprano wrote:
> On Wed, Apr 15, 2015 at 08:21:33AM -0400, Ken G. wrote:
>> When running the following code, I get the following
>> error code:
>>
>> 201504110102030405061
>> Traceback (most recent call last):
>>    File "Mega_Millions_Tickets_Change.py", line 11, in <module>
>>      datecode[20:21] = "0"
>> TypeError: 'str' object does not support item assignment
> Try this:
>
> datacode = datacode[:20] + "0" + datacode[21:]
>
>
> This is called "slicing". We take a slice of the string, from the start up to just before position 20; "0"; and a slice from position 21 to the end of the string. The three pieces are then concatenated together, giving a new string.
Wow! So darn simple with a good explanation. Thanks!

Ken


From steve at pearwood.info  Wed Apr 15 15:29:08 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 15 Apr 2015 23:29:08 +1000
Subject: [Tutor] How to get a Tkinter window to print a color copy of
	itself as a .pdf file?
In-Reply-To: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
Message-ID: <20150415132908.GK5663@ando.pearwood.info>

On Wed, Apr 15, 2015 at 07:55:28AM -0500, boB Stepp wrote:
> Solaris 10, Python 2.4.4
> 
> I have very little experience with issuing print commands using a Unix
> environment. Despite this, I wish to design a Tkinter window with a
> "Print" button, which, when clicked, would create a copy of the
> contents of the window as a .pdf file. GhostScript is available on my
> systems.
> 
> I know that the Canvas container has the ability to print itself to a
> postscript file, but I do not want to use Canvas as my container
> object.

You will excuse me, I hope, but I'm afraid that comes across as rather 
foolish:

"I want to hammer this nail into this piece of wood. I have a hammer, 
but I don't want to use a hammer. I would prefer to use a saw, or 
perhaps a paint brush. How can I do this?"


Why don't you want to use a Canvas? That sounds like it will solve your 
problem. Use a Canvas as the container, give it a button, and have the 
button send a message to the Canvas saying "Print yourself to PDF 
file!"

If you explain why you don't wish to use a Canvas, perhaps we can 
suggest a solution that doesn't involve trying to hammer nails with 
paint brushes.


-- 
Steve

From robertvstepp at gmail.com  Wed Apr 15 15:37:35 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 15 Apr 2015 08:37:35 -0500
Subject: [Tutor] How to get a Tkinter window to print a color copy of
 itself as a .pdf file?
In-Reply-To: <20150415132908.GK5663@ando.pearwood.info>
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
 <20150415132908.GK5663@ando.pearwood.info>
Message-ID: <CANDiX9KUxBuXNVcc_S=ofUGV678t-ZK=XwJDM=y1K_X1Rpxntg@mail.gmail.com>

On Wed, Apr 15, 2015 at 8:29 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Wed, Apr 15, 2015 at 07:55:28AM -0500, boB Stepp wrote:
>> Solaris 10, Python 2.4.4
>>
>> I have very little experience with issuing print commands using a Unix
>> environment. Despite this, I wish to design a Tkinter window with a
>> "Print" button, which, when clicked, would create a copy of the
>> contents of the window as a .pdf file. GhostScript is available on my
>> systems.
>>
>> I know that the Canvas container has the ability to print itself to a
>> postscript file, but I do not want to use Canvas as my container
>> object.
>
> You will excuse me, I hope, but I'm afraid that comes across as rather
> foolish:
>
> "I want to hammer this nail into this piece of wood. I have a hammer,
> but I don't want to use a hammer. I would prefer to use a saw, or
> perhaps a paint brush. How can I do this?"
>
>
> Why don't you want to use a Canvas? That sounds like it will solve your
> problem. Use a Canvas as the container, give it a button, and have the
> button send a message to the Canvas saying "Print yourself to PDF
> file!"
>
> If you explain why you don't wish to use a Canvas, perhaps we can
> suggest a solution that doesn't involve trying to hammer nails with
> paint brushes.

Perhaps I am being foolish! But I do have my reasons, which, in this
case, is I wanted to take advantage of the pack and grid geometry
managers. These two tools seem to make the positioning of the widgets
much easier. Unless I am missing something, in a Canvas container I
will have to assign pixel coordinates for everything, which sounds
like a lot more work!

In any event, I *would* like to know how to solve the original
problem, creating a print button that will print the contents of its
overall container object.



-- 
boB

From zachary.ware+pytut at gmail.com  Wed Apr 15 15:50:27 2015
From: zachary.ware+pytut at gmail.com (Zachary Ware)
Date: Wed, 15 Apr 2015 08:50:27 -0500
Subject: [Tutor] How to get a Tkinter window to print a color copy of
 itself as a .pdf file?
In-Reply-To: <CANDiX9KUxBuXNVcc_S=ofUGV678t-ZK=XwJDM=y1K_X1Rpxntg@mail.gmail.com>
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
 <20150415132908.GK5663@ando.pearwood.info>
 <CANDiX9KUxBuXNVcc_S=ofUGV678t-ZK=XwJDM=y1K_X1Rpxntg@mail.gmail.com>
Message-ID: <CAKJDb-POimjQikV=0hj-312hxE=B3YeAKRPFY7Le_6QW-fd2kg@mail.gmail.com>

On Apr 15, 2015 9:38 AM, "boB Stepp" <robertvstepp at gmail.com> wrote:
> Perhaps I am being foolish! But I do have my reasons, which, in this
> case, is I wanted to take advantage of the pack and grid geometry
> managers. These two tools seem to make the positioning of the widgets
> much easier. Unless I am missing something, in a Canvas container I
> will have to assign pixel coordinates for everything, which sounds
> like a lot more work!

Couldn't you just map a single Frame widget on the canvas, and use the
Frame as your "outer" container?

--
Zach
On a phone

From robertvstepp at gmail.com  Wed Apr 15 15:58:26 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 15 Apr 2015 08:58:26 -0500
Subject: [Tutor] How to get a Tkinter window to print a color copy of
 itself as a .pdf file?
In-Reply-To: <CAKJDb-POimjQikV=0hj-312hxE=B3YeAKRPFY7Le_6QW-fd2kg@mail.gmail.com>
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
 <20150415132908.GK5663@ando.pearwood.info>
 <CANDiX9KUxBuXNVcc_S=ofUGV678t-ZK=XwJDM=y1K_X1Rpxntg@mail.gmail.com>
 <CAKJDb-POimjQikV=0hj-312hxE=B3YeAKRPFY7Le_6QW-fd2kg@mail.gmail.com>
Message-ID: <CANDiX9KxDkn5u3r6GvwnYynwi_4uHtmPGjFL=9Bp42b4t-cR0Q@mail.gmail.com>

On Wed, Apr 15, 2015 at 8:50 AM, Zachary Ware
<zachary.ware+pytut at gmail.com> wrote:
>
> On Apr 15, 2015 9:38 AM, "boB Stepp" <robertvstepp at gmail.com> wrote:
>> Perhaps I am being foolish! But I do have my reasons, which, in this
>> case, is I wanted to take advantage of the pack and grid geometry
>> managers. These two tools seem to make the positioning of the widgets
>> much easier. Unless I am missing something, in a Canvas container I
>> will have to assign pixel coordinates for everything, which sounds
>> like a lot more work!
>
> Couldn't you just map a single Frame widget on the canvas, and use the Frame
> as your "outer" container?

You are SMART, I am NOT! That sounds like a great idea!!

Is this the intent of the Tkinter design to provide print
functionality? To always start with a Canvas container?

-- 
boB

From __peter__ at web.de  Wed Apr 15 17:39:53 2015
From: __peter__ at web.de (Peter Otten)
Date: Wed, 15 Apr 2015 17:39:53 +0200
Subject: [Tutor] How to get a Tkinter window to print a color copy of
	itself as a .pdf file?
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
Message-ID: <mgm0oa$i28$1@ger.gmane.org>

boB Stepp wrote:

> Solaris 10, Python 2.4.4
> 
> I have very little experience with issuing print commands using a Unix
> environment. Despite this, I wish to design a Tkinter window with a
> "Print" button, which, when clicked, would create a copy of the
> contents of the window as a .pdf file. GhostScript is available on my
> systems.
> 
> I know that the Canvas container has the ability to print itself to a
> postscript file, but I do not want to use Canvas as my container
> object. So I am hopeful this is as simple as discovering the proper
> command to associate with a button, which will generate a color
> postscript file of the containing window. Once I can get that file, I
> know how to get a .pdf out of it.
> 
> The main software that we use on these systems has this print command
> associated with its color printer *button*:
> 
> lp -c -d ricoh -o resolution=1200 -o profile=photo -o dithering=photo
> -o colorsettings=superfine -o black=k -o papper=letter -o itray=tray1
> 
> BTW, "papper" is what is actually in this software product's color
> printer settings. But can this be correct? Anyway, it does print to
> *paper*!
> 
> I suspect that some variant of this command associated with a print
> button would print *something*, but how do I get it to print the
> specific window containing the to-be-designed print button? Also, I
> need it to print a postscript file, not print to paper. I suspect this
> is another configuration setting that I need to research.
> 
> As always, many thanks in advance!

I'm on linux and surprisingly

subprocess.call(["import", "-window", window_title, postscript_file])

worked. I admit it's a roundabout way...

Here's the complete experiment; I ran it with Python 2.7, but that shouldn't 
make a difference.

import Tkinter as tk
import subprocess

window_title = "gewizzede"
postscript_file = "tmp_snapshot.ps"

def print_canvas():
#    canvas.postscript(file="tmp.ps")
    subprocess.call(["import", "-window", window_title, postscript_file])

root = tk.Tk()
root.title(window_title)

canvas = tk.Canvas(root, width=200, height=200)
canvas.pack()

button = tk.Button(root, text="Print", command=print_canvas)
button.pack()

demo = tk.Button(root, text = "demo widget button")
canvas.create_window(50, 50, window=demo)
canvas.create_rectangle(25, 25, 75, 150, fill="red")
root.mainloop()

You might guess from the above that I tried Zachary's suggestion first, but 
that printed only the red rectangle, not the demo button.


From zachary.ware at gmail.com  Wed Apr 15 16:04:58 2015
From: zachary.ware at gmail.com (Zachary Ware)
Date: Wed, 15 Apr 2015 09:04:58 -0500
Subject: [Tutor] How to get a Tkinter window to print a color copy of
 itself as a .pdf file?
In-Reply-To: <CANDiX9KxDkn5u3r6GvwnYynwi_4uHtmPGjFL=9Bp42b4t-cR0Q@mail.gmail.com>
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
 <20150415132908.GK5663@ando.pearwood.info>
 <CANDiX9KUxBuXNVcc_S=ofUGV678t-ZK=XwJDM=y1K_X1Rpxntg@mail.gmail.com>
 <CAKJDb-POimjQikV=0hj-312hxE=B3YeAKRPFY7Le_6QW-fd2kg@mail.gmail.com>
 <CANDiX9KxDkn5u3r6GvwnYynwi_4uHtmPGjFL=9Bp42b4t-cR0Q@mail.gmail.com>
Message-ID: <CAKJDb-P75ZdjmO+bo3gw8rSLkCrdgTG5UrVSLaT8zwzowcTzpA@mail.gmail.com>

On Apr 15, 2015 9:59 AM, "boB Stepp" <robertvstepp at gmail.com> wrote:
>
> On Wed, Apr 15, 2015 at 8:50 AM, Zachary Ware
> <zachary.ware+pytut at gmail.com> wrote:
> >
> > On Apr 15, 2015 9:38 AM, "boB Stepp" <robertvstepp at gmail.com> wrote:
> >> Perhaps I am being foolish! But I do have my reasons, which, in this
> >> case, is I wanted to take advantage of the pack and grid geometry
> >> managers. These two tools seem to make the positioning of the widgets
> >> much easier. Unless I am missing something, in a Canvas container I
> >> will have to assign pixel coordinates for everything, which sounds
> >> like a lot more work!
> >
> > Couldn't you just map a single Frame widget on the canvas, and use the
Frame
> > as your "outer" container?
>
> You are SMART, I am NOT! That sounds like a great idea!!

To almost quote Jacob Kaplan-Moss from his keynote talk at PyCon this year,
"Hi, I'm [Zach], and I'm a mediocre programmer" :)

> Is this the intent of the Tkinter design to provide print
> functionality? To always start with a Canvas container?

I honestly have no idea.

--
Zach
On a phone

From alan.gauld at btinternet.com  Wed Apr 15 17:57:49 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 15 Apr 2015 16:57:49 +0100
Subject: [Tutor] Regular expression on python
In-Reply-To: <mgl78s$g4a$1@ger.gmane.org>
References: <2056323956.1540771428928147594.JavaMail.httpd@webmail-58.iol.local>
 <20150414014816.GC5663@ando.pearwood.info> <mgihfg$ep4$1@ger.gmane.org>
 <20150414122124.GE5663@ando.pearwood.info> <mgk925$f6p$1@ger.gmane.org>
 <20150415010259.GH5663@ando.pearwood.info> <mgl3d6$mj2$1@ger.gmane.org>
 <mgl78s$g4a$1@ger.gmane.org>
Message-ID: <mgm1ps$6ed$1@ger.gmane.org>

On 15/04/15 09:24, Peter Otten wrote:

>> function call. I've never seen (or noticed?) the embedded form,
>> and don't see it described in the docs anywhere
>
> Quoting <https://docs.python.org/dev/library/re.html>:
>
> """
> (?aiLmsux)
> (One or more letters from the set 'a', 'i', 'L', 'm', 's', 'u', 'x'.) The
> group matches the empty string; the letters set the corresponding flags:

Aha. The trick is knowing the correct search string... I tried 'flag' 
and 'verbose' but missed this entry.

>> Again, where is that described?
>
> """
> (?#...)
> A comment; the contents of the parentheses are simply ignored.
> """

OK, I missed that too.
Maybe I just wasn't awake enough this morning! :-)

Thanks Peter.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Wed Apr 15 18:13:40 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 15 Apr 2015 17:13:40 +0100
Subject: [Tutor] How to get a Tkinter window to print a color copy of
 itself as a .pdf file?
In-Reply-To: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
Message-ID: <mgm2nj$mp4$1@ger.gmane.org>

On 15/04/15 13:55, boB Stepp wrote:
> Solaris 10, Python 2.4.4
>
> I have very little experience with issuing print commands using a Unix
> environment. Despite this, I wish to design a Tkinter window with a
> "Print" button, which, when clicked, would create a copy of the
> contents of the window as a .pdf file. GhostScript is available on my
> systems.

Your problem is that Tkinter does not really support the concept
of printing to hard copy. Other GUI frameworks (like WxPython)
do this much better. So anything you do will be a bit of a kluge.
There are some valid reasons for this: printing is extremely OS 
dependant. And Tk as a cross OS platform doesn't want to have
to deal with all the complexity(*).

The usual solution is to render the output in some print
friendly file format (html, groff, SVG etc) and then send that
to the appropriate print command. However if you really want
a screen image you might be better invoking one of the many
screen capture programs and then printing its output?

(*)
The main culprits are
- Windows which uses a "Device Context" to render its UI. The device can 
be either a screen or a printer (or notionally anything else) so in 
theory you just swap the DC and send the GUI to the new device. In 
practice its not that easy.
- MacOSX uses a Cocoa framework which, in turn, uses OpenGL primitives 
to render the UI and like Windows can theoretically render the UI on non 
screen devices, It can also render it as PDF natively which is how it 
normally prints screen images.
- *nix usually relies on rendering the output *content* on a new device 
or in a new format. Printing screenshots in generic Unix is a bit of an 
afterthought IMHO...Possibly a consequence of X having been designed 
before the days of affordable colour printers - the same reason Steve 
Jobs didn't bother with colour on the early Macs - if you couldn't print 
it, there was no point, he thought...

Printing UI images and WYSIWYG type output is one of the few triggers 
that drive me to WxPython. It handles it much more easily than Tk.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From robertvstepp at gmail.com  Wed Apr 15 19:00:43 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 15 Apr 2015 12:00:43 -0500
Subject: [Tutor] How to get a Tkinter window to print a color copy of
 itself as a .pdf file?
In-Reply-To: <mgm0oa$i28$1@ger.gmane.org>
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
 <mgm0oa$i28$1@ger.gmane.org>
Message-ID: <CANDiX9K=BzV1SG3ZM4GyE_CbRDanThPcy8p-y88eLPtW5M-d+w@mail.gmail.com>

On Wed, Apr 15, 2015 at 10:39 AM, Peter Otten <__peter__ at web.de> wrote:
> boB Stepp wrote:
>
>> Solaris 10, Python 2.4.4

[...]

>
> I'm on linux and surprisingly
>
> subprocess.call(["import", "-window", window_title, postscript_file])
>
> worked. I admit it's a roundabout way...

I did not find the "import" command in my Unix reference, but found it
in the man pages on my Solaris workstation. It looks like this should
work without having to use the Canvas container, which was what I was
originally asking about.

> Here's the complete experiment; I ran it with Python 2.7, but that shouldn't
> make a difference.

Yes, it ran fine on Python 2.4.4.

> import Tkinter as tk

Question: I have been using "from Tkinter import *" as suggested in
"Programming Python" by Lutz. He remarks that unlike other situations,
this is generally safe with Tkinter. Is there a benefit to doing the
import as you have?

> import subprocess
>
> window_title = "gewizzede"
> postscript_file = "tmp_snapshot.ps"
>
> def print_canvas():
> #    canvas.postscript(file="tmp.ps")
>     subprocess.call(["import", "-window", window_title, postscript_file])

At first I thought you had a typo here, but now I understand that "#
canvas.postscript(file="tmp.ps")" only gave you the window framework.
When I made my attempt to employ Zach's suggestion by embedding my
existing frames within a Canvas, I only got an empty white rectangle.
After searching online for that, I found references that Canvas'
postscript method only works for objects drawn on its canvas, NOT
embedded windows, frames, etc. This had me scratching my head again.
But then your post came in. I am very grateful for your solution!

> root = tk.Tk()
> root.title(window_title)
>
> canvas = tk.Canvas(root, width=200, height=200)
> canvas.pack()
>
> button = tk.Button(root, text="Print", command=print_canvas)
> button.pack()
>
> demo = tk.Button(root, text = "demo widget button")
> canvas.create_window(50, 50, window=demo)
> canvas.create_rectangle(25, 25, 75, 150, fill="red")
> root.mainloop()
>
> You might guess from the above that I tried Zachary's suggestion first, but
> that printed only the red rectangle, not the demo button.


-- 
boB

From robertvstepp at gmail.com  Wed Apr 15 19:07:46 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 15 Apr 2015 12:07:46 -0500
Subject: [Tutor] How to get a Tkinter window to print a color copy of
 itself as a .pdf file?
In-Reply-To: <mgm2nj$mp4$1@ger.gmane.org>
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
 <mgm2nj$mp4$1@ger.gmane.org>
Message-ID: <CANDiX9+BFBr_bRyqEHx2OJ4CY9C9_3R=sb8ZPGQbfmE+=a-=vQ@mail.gmail.com>

On Wed, Apr 15, 2015 at 11:13 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:

[...]

> Your problem is that Tkinter does not really support the concept
> of printing to hard copy. Other GUI frameworks (like WxPython)
> do this much better. So anything you do will be a bit of a kluge.
> There are some valid reasons for this: printing is extremely OS dependant.
> And Tk as a cross OS platform doesn't want to have
> to deal with all the complexity(*).

This is sounding like developing a platform-independent program
involving Tkinter and requiring printing is no easy task. Fortunately
my efforts need only run successfully on the Solaris 10 OS.

[...]

> Printing UI images and WYSIWYG type output is one of the few triggers that
> drive me to WxPython. It handles it much more easily than Tk.

I will have to keep wxPython in mind. It does not help me at work, but
for non-work projects it might be very useful. However, I should work
on mastering Tkinter first, as I am sure that all of the principles I
learn here will be generically useful for any GUI programming.

Thanks, Alan!

-- 
boB

From alan.gauld at btinternet.com  Wed Apr 15 20:42:20 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 15 Apr 2015 19:42:20 +0100
Subject: [Tutor] How to get a Tkinter window to print a color copy of
 itself as a .pdf file?
In-Reply-To: <CANDiX9K=BzV1SG3ZM4GyE_CbRDanThPcy8p-y88eLPtW5M-d+w@mail.gmail.com>
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
 <mgm0oa$i28$1@ger.gmane.org>
 <CANDiX9K=BzV1SG3ZM4GyE_CbRDanThPcy8p-y88eLPtW5M-d+w@mail.gmail.com>
Message-ID: <mgmbea$u8q$1@ger.gmane.org>

On 15/04/15 18:00, boB Stepp wrote:

>> import Tkinter as tk
>
> Question: I have been using "from Tkinter import *" as suggested in
> "Programming Python" by Lutz. He remarks that unlike other situations,
> this is generally safe with Tkinter. Is there a benefit to doing the
> import as you have?

Biggest benefit is if you ever move to Python 3 you cansimply change 
that line to

import tkinter as tk

and it carries on working (or at least until you hit some
of the other renamed modules!)

But also if you ever get to use Tix, because it is a
superset of Tkinter so you can just change to

import tix as tk

and it keeps working but you now have access to all the
Tix widgets too.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From beachkidken at gmail.com  Thu Apr 16 01:47:14 2015
From: beachkidken at gmail.com (Ken G.)
Date: Wed, 15 Apr 2015 19:47:14 -0400
Subject: [Tutor] Reference last email message...
Message-ID: <552EF882.6050606@gmail.com>

I just emailed that I was unable to correct a message in ModTools
so I went to Yahoo and made the change and then approved it.

Noticing it did not appear on the list, I checked the Activity Log
in Yahoo and it was marked Bounced!

Several days ago, we had another message correction and that
too, bounced.

Ken, FreecycleLouisville, KY, USA

From alan.gauld at btinternet.com  Thu Apr 16 02:21:26 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 16 Apr 2015 01:21:26 +0100
Subject: [Tutor] Reference last email message...
In-Reply-To: <552EF882.6050606@gmail.com>
References: <552EF882.6050606@gmail.com>
Message-ID: <mgmva5$rdu$1@ger.gmane.org>

On 16/04/15 00:47, Ken G. wrote:
> I just emailed that I was unable to correct a message in ModTools
> so I went to Yahoo and made the change and then approved it.

What is ModTools? What kind of message?
Where does Yahoo fit in?

What does any of it have to do with this list?

I'm confused.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From davea at davea.name  Thu Apr 16 02:45:15 2015
From: davea at davea.name (Dave Angel)
Date: Wed, 15 Apr 2015 20:45:15 -0400
Subject: [Tutor] Reference last email message...
In-Reply-To: <552EF882.6050606@gmail.com>
References: <552EF882.6050606@gmail.com>
Message-ID: <552F061B.9040804@davea.name>

On 04/15/2015 07:47 PM, Ken G. wrote:
> I just emailed that I was unable to correct a message in ModTools
> so I went to Yahoo and made the change and then approved it.
>
> Noticing it did not appear on the list, I checked the Activity Log
> in Yahoo and it was marked Bounced!
>
> Several days ago, we had another message correction and that
> too, bounced.
>

It's conceivable that you're referring to:

https://pypi.python.org/pypi/modtools/1.0.2

But your message is so garbled that I have no idea how to respond.

You have a gmail address, but you're somehow involved with yahoo.

You refer to "the list," but never say if it's this one.

You refer to "message correction" but there's no standard way to modify 
a message on python-tutor once it's mailed or posted. So perhaps the 
message correction and the list you're referring to are somewhere else.

Python-tutor is a limited mailing list that only takes messages from 
those who have subscribed/joined.  So perhaps you have two different 
email addresses and you've registered using gmail, and are trying to 
post using yahoo.

In any case, if it is ModTools, this is the wrong list to post 
questions.  This list is intended for usage of the Python language and 
the standard library, and while other subjects are permissible, they're 
not as likely to get good responses.

I'd suggest you email to python-list at python.org a new message, starting 
a new thread.  Be explicit about your question, supplying a URL when you 
refer to a 3rd party package, and giving python version and OS version. 
  Then show exactly what you've tried and what the result was, posting a 
full traceback if you got an exception.

-- 
DaveA

From __peter__ at web.de  Thu Apr 16 09:54:03 2015
From: __peter__ at web.de (Peter Otten)
Date: Thu, 16 Apr 2015 09:54:03 +0200
Subject: [Tutor] Star imports,
	was Re: How to get a Tkinter window to print a color copy of itself
	as a .pdf file?
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
 <mgm0oa$i28$1@ger.gmane.org>
 <CANDiX9K=BzV1SG3ZM4GyE_CbRDanThPcy8p-y88eLPtW5M-d+w@mail.gmail.com>
Message-ID: <mgnpqt$bv$1@ger.gmane.org>

boB Stepp wrote:

>> import Tkinter as tk
> 
> Question: I have been using "from Tkinter import *" as suggested in
> "Programming Python" by Lutz. He remarks that unlike other situations,
> this is generally safe with Tkinter. Is there a benefit to doing the
> import as you have?

It's a stylistic preference: I like to keep namespaces separate.

When I make an exception, typically for generic functionality like

contextmanager, groupby, namedtuple, defaultdict...

I import these in a controlled way with

from collections import defaultdict
from itertools import islice, zip_longest

etc., use them as "pseudo-builtins", and avoid writing functions with the 
same name myself. By contrast I have no clear idea of what's in the tkinter 
package and might write my own getint() function, say, thus forcing a reader 
to scan the complete module to learn which getint() is used.

This is a general problem of star imports; when you overwrite an imported 
name you typically don't care or even know about that name in the imported 
module. When you read your module later to fix or amend something your 
knowledge may have grown, and you expect the imported function where the 
custom function is used. This confusion becomes even more likely when a 
second developer is involved.


From cybervigilante at gmail.com  Thu Apr 16 07:03:59 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Wed, 15 Apr 2015 22:03:59 -0700
Subject: [Tutor] Fraction - differing interpretations for number and string
Message-ID: <CALRAYNXyv4Zbuy0Yv6etQ6_Q5HjrEe4RSQdv7dX5XVwFQqYfFw@mail.gmail.com>

Why does Fraction interpret a number and string so differently? They come
out the same, but it seems rather odd

>>> from fractions import Fraction
>>> Fraction(1.64)
Fraction(7385903388887613, 4503599627370496)
>>> Fraction("1.64")
Fraction(41, 25)
>>> 41/25
1.64
>>> 7385903388887613 / 4503599627370496
1.64

-- 
Jim

"Greetings, Windows user. Your installation of Linux has been blocked. You
are our bitch forever, HaHaHaHaHa!" --signed, your friends at Microsoft

From danny.yoo at gmail.com  Thu Apr 16 10:52:51 2015
From: danny.yoo at gmail.com (Danny Yoo)
Date: Thu, 16 Apr 2015 01:52:51 -0700
Subject: [Tutor] Fraction - differing interpretations for number and
	string
In-Reply-To: <CALRAYNXyv4Zbuy0Yv6etQ6_Q5HjrEe4RSQdv7dX5XVwFQqYfFw@mail.gmail.com>
References: <CALRAYNXyv4Zbuy0Yv6etQ6_Q5HjrEe4RSQdv7dX5XVwFQqYfFw@mail.gmail.com>
Message-ID: <CAGZAPF5QyYc66AVaXisMRUMYLOjde5fVw3APTc+Q8dD3K3eQSQ@mail.gmail.com>

On Apr 16, 2015 1:32 AM, "Jim Mooney" <cybervigilante at gmail.com> wrote:
>
> Why does Fraction interpret a number and string so differently? They come
> out the same, but it seems rather odd
>
> >>> from fractions import Fraction
> >>> Fraction(1.64)
> Fraction(7385903388887613, 4503599627370496)
> >>> Fraction("1.64")
> Fraction(41, 25)
> >>> 41/25
> 1.64
> >>> 7385903388887613 / 4503599627370496
> 1.64

In many systems, if everything is the same shape, then certain operations
might be implemented more quickly by making uniform assumptions.  If all my
clothes were the same, for example, maybe I'd be able to sorry my laundry
more quickly.  And if all my Tupperware were the same size, then maybe my
cabinets wouldn't be the nest of ill fitting plastic that it is now.

And if every number was represented with a fixed quantity of bits in a
computer, then maybe computer arithmetic could go really fast.

It's this last supposition that should be treated most seriously.  Most
computers use "floating point", a representation of numbers that use a
fixed set of bits.  This uniformity allows floating point math to be
implemented quickly.  But it also means that it's inaccurate.  You're
seeing evidence of the inaccuracy.

Read: https://docs.python.org/2/tutorial/floatingpoint.html and see if that
helps clarify.

From wolfgang.maier at biologie.uni-freiburg.de  Thu Apr 16 10:51:50 2015
From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier)
Date: Thu, 16 Apr 2015 10:51:50 +0200
Subject: [Tutor] Fraction - differing interpretations for number and
	string
In-Reply-To: <CALRAYNXyv4Zbuy0Yv6etQ6_Q5HjrEe4RSQdv7dX5XVwFQqYfFw@mail.gmail.com>
References: <CALRAYNXyv4Zbuy0Yv6etQ6_Q5HjrEe4RSQdv7dX5XVwFQqYfFw@mail.gmail.com>
Message-ID: <mgnt8u$ong$1@ger.gmane.org>

On 04/16/2015 07:03 AM, Jim Mooney wrote:
> Why does Fraction interpret a number and string so differently? They come
> out the same, but it seems rather odd
>
>>>> from fractions import Fraction
>>>> Fraction(1.64)
> Fraction(7385903388887613, 4503599627370496)
>>>> Fraction("1.64")
> Fraction(41, 25)
>>>> 41/25
> 1.64
>>>> 7385903388887613 / 4503599627370496
> 1.64
>

That is because 1.64 cannot be represented exactly as a float.
Try:

 >>> x = 1.64
 >>> format(x,'.60f')
'1.639999999999999902300373832986224442720413208007812500000000'

If you construct a Fraction from a str OTOH, Fraction assumes you meant 
exactly that number.
And in fact:

 >>> 
Fraction('1.639999999999999902300373832986224442720413208007812500000000')
Fraction(7385903388887613, 4503599627370496)


see also https://docs.python.org/3/tutorial/floatingpoint.html for an 
explanation of floating-point inaccuracies.



From danny.yoo at gmail.com  Thu Apr 16 10:55:06 2015
From: danny.yoo at gmail.com (Danny Yoo)
Date: Thu, 16 Apr 2015 01:55:06 -0700
Subject: [Tutor] Fraction - differing interpretations for number and
	string
In-Reply-To: <CAGZAPF5QyYc66AVaXisMRUMYLOjde5fVw3APTc+Q8dD3K3eQSQ@mail.gmail.com>
References: <CALRAYNXyv4Zbuy0Yv6etQ6_Q5HjrEe4RSQdv7dX5XVwFQqYfFw@mail.gmail.com>
 <CAGZAPF5QyYc66AVaXisMRUMYLOjde5fVw3APTc+Q8dD3K3eQSQ@mail.gmail.com>
Message-ID: <CAGZAPF6h2b4eVVXWJCLbJbz5j3t66XDf97PGxXJ19sV3uZPbDw@mail.gmail.com>

On Apr 16, 2015 1:52 AM, "Danny Yoo" <danny.yoo at gmail.com> wrote:
>
>
> On Apr 16, 2015 1:32 AM, "Jim Mooney" <cybervigilante at gmail.com> wrote:
> >
> > Why does Fraction interpret a number and string so differently? They
come
> > out the same, but it seems rather odd
> >
> > >>> from fractions import Fraction
> > >>> Fraction(1.64)
> > Fraction(7385903388887613, 4503599627370496)
> > >>> Fraction("1.64")
> > Fraction(41, 25)
> > >>> 41/25
> > 1.64
> > >>> 7385903388887613 / 4503599627370496
> > 1.64
>
> In many systems, if everything is the same shape, then certain operations
might be implemented more quickly by making uniform assumptions.  If all my
clothes were the same, for example, maybe I'd be able to sorry my laundry
more quickly.  And if all my Tupperware were the same size, then maybe my
cabinets wouldn't be the nest of ill fitting plastic that it is now.

Substitute "sorry" with "sort".  Sorry!  :p

From beachkidken at gmail.com  Thu Apr 16 14:03:03 2015
From: beachkidken at gmail.com (Ken G.)
Date: Thu, 16 Apr 2015 08:03:03 -0400
Subject: [Tutor] Reference last email message...
In-Reply-To: <552F061B.9040804@davea.name>
References: <552EF882.6050606@gmail.com> <552F061B.9040804@davea.name>
Message-ID: <552FA4F7.3080203@gmail.com>



On 04/15/2015 08:45 PM, Dave Angel wrote:
> On 04/15/2015 07:47 PM, Ken G. wrote:
>> I just emailed that I was unable to correct a message in ModTools
>> so I went to Yahoo and made the change and then approved it.
>>
>> Noticing it did not appear on the list, I checked the Activity Log
>> in Yahoo and it was marked Bounced!
>>
>> Several days ago, we had another message correction and that
>> too, bounced.
>>
>
> It's conceivable that you're referring to:
>
> https://pypi.python.org/pypi/modtools/1.0.2
>
> But your message is so garbled that I have no idea how to respond.
>
> You have a gmail address, but you're somehow involved with yahoo.
>
> You refer to "the list," but never say if it's this one.
>
> You refer to "message correction" but there's no standard way to 
> modify a message on python-tutor once it's mailed or posted. So 
> perhaps the message correction and the list you're referring to are 
> somewhere else.
>
> Python-tutor is a limited mailing list that only takes messages from 
> those who have subscribed/joined.  So perhaps you have two different 
> email addresses and you've registered using gmail, and are trying to 
> post using yahoo.
>
> In any case, if it is ModTools, this is the wrong list to post 
> questions.  This list is intended for usage of the Python language and 
> the standard library, and while other subjects are permissible, 
> they're not as likely to get good responses.
>
> I'd suggest you email to python-list at python.org a new message, 
> starting a new thread.  Be explicit about your question, supplying a 
> URL when you refer to a 3rd party package, and giving python version 
> and OS version.  Then show exactly what you've tried and what the 
> result was, posting a full traceback if you got an exception.
>
Oh my! I send this to the wrong address. My apology. < redfaced >

Ken

From beachkidken at gmail.com  Thu Apr 16 14:04:09 2015
From: beachkidken at gmail.com (Ken G.)
Date: Thu, 16 Apr 2015 08:04:09 -0400
Subject: [Tutor] Reference last email message...
In-Reply-To: <mgmva5$rdu$1@ger.gmane.org>
References: <552EF882.6050606@gmail.com> <mgmva5$rdu$1@ger.gmane.org>
Message-ID: <552FA539.2020204@gmail.com>



On 04/15/2015 08:21 PM, Alan Gauld wrote:
> On 16/04/15 00:47, Ken G. wrote:
>> I just emailed that I was unable to correct a message in ModTools
>> so I went to Yahoo and made the change and then approved it.
>
> What is ModTools? What kind of message?
> Where does Yahoo fit in?
>
> What does any of it have to do with this list?
>
> I'm confused.
>
Again, my apology. Sent to the wrong address. < redfaced >

Ken

From davea at davea.name  Thu Apr 16 14:11:05 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 16 Apr 2015 08:11:05 -0400
Subject: [Tutor] Fraction - differing interpretations for number and
	string
In-Reply-To: <CALRAYNXyv4Zbuy0Yv6etQ6_Q5HjrEe4RSQdv7dX5XVwFQqYfFw@mail.gmail.com>
References: <CALRAYNXyv4Zbuy0Yv6etQ6_Q5HjrEe4RSQdv7dX5XVwFQqYfFw@mail.gmail.com>
Message-ID: <552FA6D9.8010907@davea.name>

On 04/16/2015 01:03 AM, Jim Mooney wrote:
> Why does Fraction interpret a number and string so differently? They come
> out the same, but it seems rather odd
>
>>>> from fractions import Fraction
>>>> Fraction(1.64)
> Fraction(7385903388887613, 4503599627370496)
>>>> Fraction("1.64")
> Fraction(41, 25)
>>>> 41/25
> 1.64
>>>> 7385903388887613 / 4503599627370496
> 1.64
>

When a number isn't an exact integer (and sometimes when the integer is 
large enough), some common computer number formats cannot store the 
number exactly.  Naturally we know about transcendentals, which cannot 
be stored exactly in any base.  PI and E and the square-root of two are 
three well known examples.

But even rational numbers cannot be stored exactly unless they happen to 
match the base you're using to store them.  For example, 1/3 cannot be 
stored exactly in any common base.  In decimal, it'd be a repeating set 
of 3's.  And whenever you stopped putting down threes, you've made an 
approximation.
     0.3333333333

Python defaults to using a float type, which is a binary floating point 
representation that uses the special hardware available in most recent 
computers.  And in fact, when you use a literal number in your source, 
it's converted to a float by the compiler, not stored as the digits you 
typed.

The number you specified in decimal, 1.64, is never going to be stored 
in a finite number of binary bits, in a float.

 >>> from fractions import Fraction
 >>> from decimal import Decimal

 >>> y = 1.64
Conversion to float appens at compile time, so the value given to y is 
already approximate.
    roughly equivalent to the following
 >>> y = float("1.64")

 >>> Fraction(y)
Fraction(7385903388887613, 4503599627370496)

If you converted it in string form instead to Decimal, then the number 
you entered would be saved exactly.

 >>> x = Decimal("1.64")
This value is stored exactly.

 >>> x
Decimal('1.64')

 >>> Fraction(x)
Fraction(41, 25)


Sometimes it's convenient to do the conversion in our head, as it were.
Since 1.64 is shorthand for  164/100, we can just pass those integers to 
Fraction, and get an exact answer again.

 >>> Fraction(164, 100)
Fraction(41, 25)


Nothing about this says that Decimal is necessarily better than float. 
It appears better because we enter values in decimal form and to use 
float, those have to be converted, and there's frequently a loss during 
conversion.  But Decimal is slower and takes more space, so most current 
languages use binary floating point instead.

I implemented the math on a machine 40 years ago where all user 
arithmetic was done in decimal floating point.  i thought it was a good 
idea at the time because of a principle I called "least surprise." 
There were roundoff errors, but only in places where you'd get the same 
ones doing it by hand.

History has decided differently.  When the IEEE committee first met, 
Intel already had its 8087 implemented, and many decisions were based on 
what that chip could do and couldn't do.  So that standard became the 
default standard that future implementations would use, whatever company.

-- 
DaveA

From davea at davea.name  Thu Apr 16 14:15:40 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 16 Apr 2015 08:15:40 -0400
Subject: [Tutor] Fraction - differing interpretations for number and
	string
In-Reply-To: <552FA6D9.8010907@davea.name>
References: <CALRAYNXyv4Zbuy0Yv6etQ6_Q5HjrEe4RSQdv7dX5XVwFQqYfFw@mail.gmail.com>
 <552FA6D9.8010907@davea.name>
Message-ID: <552FA7EC.2020904@davea.name>

On 04/16/2015 08:11 AM, Dave Angel wrote:
> On 04/16/2015 01:03 AM, Jim Mooney wrote:
>> Why does Fraction interpret a number and string so differently? They come
>> out the same, but it seems rather odd
>>
>>>>> from fractions import Fraction
>>>>> Fraction(1.64)
>> Fraction(7385903388887613, 4503599627370496)
>>>>> Fraction("1.64")
>> Fraction(41, 25)
>>>>> 41/25
>> 1.64
>>>>> 7385903388887613 / 4503599627370496
>> 1.64
>>
>
> When a number isn't an exact integer (and sometimes when the integer is
> large enough), some common computer number formats cannot store the
> number exactly.  Naturally we know about transcendentals, which cannot
> be stored exactly in any base.  PI and E and the square-root of two are
> three well known examples.
>
> But even rational numbers cannot be stored exactly unless they happen to
> match the base you're using to store them.  For example, 1/3 cannot be
> stored exactly in any common base.

By "common" I mean 2, 8, 10, or 16.  Obviously if someone implemented a 
base 3 floating point package, the number would be simply  0.1

>  In decimal, it'd be a repeating set
> of 3's.  And whenever you stopped putting down threes, you've made an
> approximation.
>      0.3333333333
>
> Python defaults to using a float type, which is a binary floating point
> representation that uses the special hardware available in most recent
> computers.  And in fact, when you use a literal number in your source,
> it's converted to a float by the compiler, not stored as the digits you
> typed.
>
> The number you specified in decimal, 1.64, is never going to be stored
> in a finite number of binary bits, in a float.
>
>  >>> from fractions import Fraction
>  >>> from decimal import Decimal
>
>  >>> y = 1.64
> Conversion to float appens at compile time, so the value given to y is
> already approximate.
>     roughly equivalent to the following
>  >>> y = float("1.64")
>
>  >>> Fraction(y)
> Fraction(7385903388887613, 4503599627370496)
>
> If you converted it in string form instead to Decimal, then the number
> you entered would be saved exactly.
>
>  >>> x = Decimal("1.64")
> This value is stored exactly.
>
>  >>> x
> Decimal('1.64')
>
>  >>> Fraction(x)
> Fraction(41, 25)
>
>
> Sometimes it's convenient to do the conversion in our head, as it were.
> Since 1.64 is shorthand for  164/100, we can just pass those integers to
> Fraction, and get an exact answer again.
>
>  >>> Fraction(164, 100)
> Fraction(41, 25)
>
>
> Nothing about this says that Decimal is necessarily better than float.
> It appears better because we enter values in decimal form and to use
> float, those have to be converted, and there's frequently a loss during
> conversion.  But Decimal is slower and takes more space, so most current
> languages use binary floating point instead.
>
> I implemented the math on a machine 40 years ago where all user
> arithmetic was done in decimal floating point.  i thought it was a good
> idea at the time because of a principle I called "least surprise." There
> were roundoff errors, but only in places where you'd get the same ones
> doing it by hand.
>
> History has decided differently.  When the IEEE committee first met,
> Intel already had its 8087 implemented, and many decisions were based on
> what that chip could do and couldn't do.  So that standard became the
> default standard that future implementations would use, whatever company.
>


-- 
DaveA

From adeadmarshal at gmail.com  Thu Apr 16 12:00:29 2015
From: adeadmarshal at gmail.com (Ali Moradi)
Date: Thu, 16 Apr 2015 14:30:29 +0430
Subject: [Tutor] making a list in Tkinter with clickable items (Python 2.x)
Message-ID: <CAMh2k3bg5WDLzN12S0zz02LBeeL1T8tbPOTzkd+NfHGsov0hog@mail.gmail.com>

Hi, i want to load a bunch of words from my database into the listbox in
Tkinter, make them clickable, and when i clicked on them the specific
meaning of that word apears in a textbox beside the listbox.

i have a code but it's not complete. i'm a beginner in Python :(

code:
#!/bin/python
from tkinter import *
from tkinter import ttk

def z():
    global entry
    if(lb.get(lb.curselection())):
        txt.insert(END, lb.get(lb.curselection()))


root = Tk()

entry = ttk.Entry(root);entry.grid(row = 0, column = 0)


lb = Listbox(root)

a=lb.insert(1, "crime")
b=lb.insert(2, "murder")
lb.insert(3, "get")
lb.insert(4, "take")

Button(root, text="BUtt", command=z).grid()

lb.grid(row = 1, column = 0)

scroll = Scrollbar(root, orient = VERTICAL, command = lb.yview)
scroll.grid(row = 0, column = 1, sticky = 'ns')
lb.config(yscrollcommand = scroll.set)

txt = Text(root, width = 60, height = 30,)
txt.grid(row = 1, column = 2)

root.mainloop()
-----------------------------------
thanks.

From steve at pearwood.info  Thu Apr 16 15:51:42 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 16 Apr 2015 23:51:42 +1000
Subject: [Tutor] Fraction - differing interpretations for number and
	string
In-Reply-To: <CAGZAPF5QyYc66AVaXisMRUMYLOjde5fVw3APTc+Q8dD3K3eQSQ@mail.gmail.com>
References: <CALRAYNXyv4Zbuy0Yv6etQ6_Q5HjrEe4RSQdv7dX5XVwFQqYfFw@mail.gmail.com>
 <CAGZAPF5QyYc66AVaXisMRUMYLOjde5fVw3APTc+Q8dD3K3eQSQ@mail.gmail.com>
Message-ID: <20150416135141.GP5663@ando.pearwood.info>

On Thu, Apr 16, 2015 at 01:52:51AM -0700, Danny Yoo wrote:

> It's this last supposition that should be treated most seriously.  Most
> computers use "floating point", a representation of numbers that use a
> fixed set of bits.  This uniformity allows floating point math to be
> implemented quickly.  But it also means that it's inaccurate.  You're
> seeing evidence of the inaccuracy.

Hmmm. I wouldn't describe it as "inaccurate". The situation is a lot 
more subtle and complicated than mere inaccuracy, especially these days.

Back when dinosaurs ruled the earth, it would be accurate to describe 
floating point arithmetic as "inaccurate", pun intended. Some of the 
biggest companies in computing back in the 1970s had floating point 
arithmetic which was horrible. I'm aware of at least one system where 
code like this:

    if x != 0:
        print 1/x

could crash with a Divide By Zero error. And worse! But since IEEE-754 
floating point semantics has become almost universal, the situation is 
quite different. IEEE-754 guarantees that the four basic arithmetic 
operations + - * / will give the closest possible result to the exact 
mathematical result, depending on the rounding mode and available 
precision. If an IEEE-754 floating point system gives a result for some 
operation like 1/x, you can be sure that this result is the closest you 
can possibly get to the true mathematical result -- and is often exact.

The subtlety is that the numbers you type in decimal are not always the 
numbers the floating point system is actually dealing with, because they 
cannot be. What you get though, is the number closest possible to what 
you want.

Let me explain with an analogy. We all know that the decimal for 1/3 is 
0.33333-repeating, with an infinite number of threes after the decimal 
point. That means any decimal number you can possibly write down is not 
1/3 exactly, it will either be a tiny bit less, or a tiny bit more.

    0.333333333      # pretty close
    0.33333333333    # even closer
    0.3333333333333  # closer, but still not exact
    0.3333333333334  # too big

There is no way to write 1/3 exactly as a decimal, and no way to 
calculate it exactly as a decimal either. If you ask for 1/3 you will 
get something either a tiny bit smaller than 1/3 or a tiny bit bigger.

Computer floating point numbers generally use base 2, not base 10. That 
means that fractions like 1/2, 1/4, 1/8 and similar can be represented 
exactly (up to the limit of available precision) but many decimal 
numbers are like 1/3 in decimal and have an infinitely repeating binary 
form. Since we don't have an infinite amount of memory, we cannot 
represent them *exactly* as binary floats.

So the decimal fraction 0.5 means 5/10 or if you prefer, (5 * 1/10). 
That is the same as "1/2" or (1 * 1/2), which means that in base-2 we 
can write it as "0.1".

0.75 in decimal means (7 * 1/10 + 5 * 1/100). With a bit of simple 
arithmetic, you should be able to work out that 0.75 is also equal to 
(1/2 + 1/4), or to put it another way, (1 * 1/2 + 1 * 1/4) which can be 
written as "0.11" in base-2.

But the simple decimal number 0.1 cannot be written in an exact base-2 
form:

1/10 is smaller than 1/2, so base-2 "0.1" is too big;
1/10 is smaller than 1/4, so base-2 "0.01" is too big;
1/10 is smaller than 1/8, so base-2 "0.001" is too big;

1/10 is bigger than 1/16, so base-2 "0.0001" is too small;
1/10 is bigger than 1/16 + 1/32, so base-2 "0.00011" is too small;
1/10 is smaller than 1/16 + 1/32 + 1/64, so base-2 "0.000111" 
     is too big;

likewise base-2 "0.0001101" is too big (1/16 + 1/32 + 1/128);
base-2 "0.00011001" is too small (1/16 + 1/32 + 1/256);
and so on.

What we actually need is the infinitely repeating binary number:

0.00011001100110011001100110011...

where the 0011s repeat forever. But we cannot do that, since floats only 
have a fixed number of bits. We have to stop the process somewhere, and 
get something a tiny bit too small:

0.0001100110011001100110

or a tiny bit too big:

0.0001100110011001100111

depending on exactly how many bits we have available.

Is this "inaccurate"? Well, in the sense that it is not the exact true 
mathematical result, yes it is, but that term can be misleading if you 
think of it as "a mistake". In another sense, it's not inaccurate, it is 
as accurate as possible (given the limitation of only having a certain 
fixed number of bits). 



-- 
Steve

From alan.gauld at btinternet.com  Thu Apr 16 18:12:49 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 16 Apr 2015 17:12:49 +0100
Subject: [Tutor] making a list in Tkinter with clickable items (Python
	2.x)
In-Reply-To: <CAMh2k3bg5WDLzN12S0zz02LBeeL1T8tbPOTzkd+NfHGsov0hog@mail.gmail.com>
References: <CAMh2k3bg5WDLzN12S0zz02LBeeL1T8tbPOTzkd+NfHGsov0hog@mail.gmail.com>
Message-ID: <mgon20$st1$1@ger.gmane.org>

On 16/04/15 11:00, Ali Moradi wrote:
> Hi, i want to load a bunch of words from my database into the listbox in
> Tkinter, make them clickable, and when i clicked on them the specific
> meaning of that word apears in a textbox beside the listbox.
>
> i have a code but it's not complete. i'm a beginner in Python :(
>

Focus on getting your UI working first. There are lots of problems 
below. Sort those then you can focus on the sing;e problem of managing 
the data, followed by the next single problem of clicking on an item to 
do something.

For now get your foundation working.

> code:
> #!/bin/python
> from tkinter import *
> from tkinter import ttk

If its Python v2 then you spell it Tkinter (capital T).
And ttk lives at the top level in Python 2 not under Tkinter.


> def z():
>      global entry
>      if(lb.get(lb.curselection())):
>          txt.insert(END, lb.get(lb.curselection()))

Please use descriptive names for functions, it makes
reading the code much easier.

Why use global entry when you don't use entry in your function?

Also its better practice to use a variable to store the current 
selection rather than ask for it twice:

def transferCurrentSelection():
     sel = lb.curselection()
     content = lb.get(sel)
     if content:
        txt.insert(END, content)

Its a lot easier to debug if things go wrong. And you can
more easily tweak it to become a reusable function too...

> root = Tk()
>
> entry = ttk.Entry(root);entry.grid(row = 0, column = 0)

Don't use semi-colons like that, it confuses the code and
is very hard to see and differentiate from a period.
Nobody will shout at you for using two lines.

> lb = Listbox(root)
>
> a=lb.insert(1, "crime")
> b=lb.insert(2, "murder")
> lb.insert(3, "get")
> lb.insert(4, "take")

Why store a and b but not the other two results?
In fact insert() returns None anyway so storing
it is pointless.

> Button(root, text="BUtt", command=z).grid()
>
> lb.grid(row = 1, column = 0)

Its usually better to keep the geometry manager lines
beside the widget creation lines. It doesn't hurt if
you pack/grid the widget before populating it.

> scroll = Scrollbar(root, orient = VERTICAL, command = lb.yview)
> scroll.grid(row = 0, column = 1, sticky = 'ns')
> lb.config(yscrollcommand = scroll.set)

You could have set this when creating the Listbox.
Having random lines of code hidden among other widget code
makes debugging much harder.

> txt = Text(root, width = 60, height = 30,)
> txt.grid(row = 1, column = 2)
>
> root.mainloop()

Once you get this working we can revisit the matter of
retrieving data from a database, populating the list box
and then associating the clicked result with a meaning
(from the database presumably?).


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From robertvstepp at gmail.com  Thu Apr 16 18:47:43 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Thu, 16 Apr 2015 11:47:43 -0500
Subject: [Tutor] How (not!) lengthy should functions be?
Message-ID: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>

As I go through my current coding project(s) I find myself breaking
functions down into other functions, especially when I see see
(unnecessarily) duplicated code fragments. I understand this to be
regarded as good practice. However, I am wondering if I am carrying
things too far? For instance I have a collection of functions that do
simple units conversions such as:

def percent2Gy(dose_percent, target_dose_cGy):
   """
   Convert a dose given as a percent of target dose into Gy (Gray).
   """
   dose_Gy = cGy2Gy((dose_percent / 100.0) * target_dose_cGy)
   return dose_Gy

This function calls another units conversion function, cGy2Gy(), in
doing its work. Generally speaking, I have units conversions functions
for every conversion I currently need to do plus some that I am not
using yet because I can easily see the need for them in the future.

My current understanding of function length best practice is that: 1)
Each function should have preferably ONE clearly defined purpose. 2) I
have seen varying recommendations as to number of lines of code per
function, but I have seem multiple recommendations that a function
generally should fit into one screen on one's monitor. Of course, some
people have HUGE monitors! And I assume that any guidance applies
equally well to methods.

Am I on-track or am I getting carried away?

-- 
boB

From dyoo at hashcollision.org  Thu Apr 16 19:45:07 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Thu, 16 Apr 2015 10:45:07 -0700
Subject: [Tutor] How (not!) lengthy should functions be?
In-Reply-To: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
Message-ID: <CAGZAPF4uY8vFKcBz2NCqVSfvXrj0=M0zenO9_MzqYf2EN0GMvw@mail.gmail.com>

> My current understanding of function length best practice is that: 1)
> Each function should have preferably ONE clearly defined purpose.

Purpose is the biggest factor for me.


> 2) I  have seen varying recommendations as to number of lines of code per
> function,

I don't weight this as heavily.  I guess I treat physical metrics
mostly like guidelines... except for line length, for arbitrary
reasons.  :P.  Anything that goes longer than 80 characters just makes
me uncomfortable.

I do like short functions, but if some block of code is a few lines
longer than average, that's probably ok.  What I'd be looking at more
closely is the complexity of the statements *in* the function.  "Is
the function deeply nested?", for example.

Just to add: I find that unit testing has an influence on me that
encourages writing shorter functions, mostly because the unit testing
forces me to make sure the function's easy to test.  Kent Beck's "Test
Driven Development by Example" talks about this in more depth.

From __peter__ at web.de  Thu Apr 16 20:43:47 2015
From: __peter__ at web.de (Peter Otten)
Date: Thu, 16 Apr 2015 20:43:47 +0200
Subject: [Tutor] How (not!) lengthy should functions be?
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
Message-ID: <mgovt3$ipn$1@ger.gmane.org>

boB Stepp wrote:

> As I go through my current coding project(s) I find myself breaking
> functions down into other functions, especially when I see see
> (unnecessarily) duplicated code fragments. I understand this to be
> regarded as good practice. However, I am wondering if I am carrying
> things too far? For instance I have a collection of functions that do
> simple units conversions such as:
> 
> def percent2Gy(dose_percent, target_dose_cGy):
>    """
>    Convert a dose given as a percent of target dose into Gy (Gray).
>    """
>    dose_Gy = cGy2Gy((dose_percent / 100.0) * target_dose_cGy)
>    return dose_Gy
> 
> This function calls another units conversion function, cGy2Gy(), in
> doing its work. Generally speaking, I have units conversions functions
> for every conversion I currently need to do plus some that I am not
> using yet because I can easily see the need for them in the future.
> 
> My current understanding of function length best practice is that: 1)
> Each function should have preferably ONE clearly defined purpose. 2) I
> have seen varying recommendations as to number of lines of code per
> function, but I have seem multiple recommendations that a function
> generally should fit into one screen on one's monitor. Of course, some
> people have HUGE monitors! And I assume that any guidance applies
> equally well to methods.
> 
> Am I on-track or am I getting carried away?

Normally I just stress that functions cannot get too short as both beginners 
and smart people tend to make them too long. As far as I'm concerned a 
function with a single line is fine while a function with more than 10 lines 
needs justification.

However, there's more to it. You are working in an environment where people 
may be harmed if you get your numbers wrong, and nothing hinders you to swap 
the arguments in your percent2Gy() function or even pass it a length and an 
amount of dollars. You need measures to make this unlikely.

Unambiguous function names and keyword-only parameters (not available in 
Python 2) and of course tests help, but you might also consider custom types 
that are restricted to a well-defined set of operations. A sketch:

# For illustration purpose only!
class Percent:
    def __init__(self, value):
        if value < 1 or value > 100: # XXX allow 0%?
            raise ValueError
        self.value = value
    def factor(self):
        return self.value / 100.0
    def __repr__(self):
        return "{} %".format(self.value)

class DoseInGray:
    def __init__(self, value, **comment):
        self.value = value
        self.comment = comment.pop("comment", "<no comment>")
        if comment:
            raise TypeEror
    def __repr__(self):
        return "{} Gy # {}".format(self.value, self.comment)
    def __str__(self):
        return  "{} Gy".format(self.value)

class TargetDoseInGray:
    def __init__(self, value):
        self.value = value
    def partial_dose(self, percent):
        if not isinstance(percent, Percent):
            raise TypeError
        return DoseInGray(
            self.value * percent.factor(),
            comment="{} of the target dose".format(percent))
    def __str__(self):
        return "{} Gy".format(self.value)


if __name__ == "__main__":
    target_dose = TargetDoseInGray(20)
    print target_dose
    
    partial_dose = target_dose.partial_dose(Percent(10))
    print partial_dose
    print repr(partial_dose)

    target_dose.partial_dose(0.1) # raises TypeError

Output:

$ python gray.py 
20 Gy
2.0 Gy
2.0 Gy # 10 % of the target dose
Traceback (most recent call last):
  File "gray.py", line 43, in <module>
    target_dose.partial_dose(0.1) # raises TypeError
  File "gray.py", line 27, in partial_dose
    raise TypeError
TypeError

OK, I got carried away a bit with my example, but you might get an idea 
where I'm aiming at. The way I wrote it it is pretty clear that Percent(10) 
denote 10 rather than 1000 %.

I can't spare you a last remark: Python may not be the right language to 
make this bulletproof.


From ben+python at benfinney.id.au  Thu Apr 16 22:21:14 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Fri, 17 Apr 2015 06:21:14 +1000
Subject: [Tutor] How (not!) lengthy should functions be?
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
Message-ID: <85egnju8n9.fsf@benfinney.id.au>

boB Stepp <robertvstepp at gmail.com> writes:

> My current understanding of function length best practice is that: 1)
> Each function should have preferably ONE clearly defined purpose.

Yes, that's a principle to follow firmly, improving the design every
time. I know of no exceptions.

?Clearly defined? also entails the function signature (its name, what
parameters it accepts, what return value it emits) is narrowly defined.

> 2) I have seen varying recommendations as to number of lines of code
> per function, but I have seem multiple recommendations that a function
> generally should fit into one screen on one's monitor.

A function that is clearly-designed, as above, should have no more than
a handful of statements. That's intentionally vague, but it's already
shorter than ?a screenful?.

> Of course, some people have HUGE monitors! And I assume that any
> guidance applies equally well to methods.

Any function with statements stretching over 20 lines is already too
large, IMO.

Note that the docstring can be rather lengthy, if there is a lot to say
about the function's purpose or strange cases it handles.

> Am I on-track or am I getting carried away?

You're right to care about precision in your code. Overlong, overbroad,
overcomplex, overdetermined functions happen through laziness; it takes
diligence to keep the code readable through refactoring while you go.
That takes more effort at each edit, but saves a lot of debugging time.

Having such a principle in mind, and knowing that it's worth spending
effort to uphold, will serve you well.

-- 
 \         ?Outside of a dog, a book is man's best friend. Inside of a |
  `\                        dog, it's too dark to read.? ?Groucho Marx |
_o__)                                                                  |
Ben Finney


From cybervigilante at gmail.com  Thu Apr 16 19:24:47 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Thu, 16 Apr 2015 10:24:47 -0700
Subject: [Tutor] Fraction - differing interpretations for number and
 string - presentation
Message-ID: <CALRAYNXb-cdhhob5GnCp2uRq5fqd_PkxvskEsBR2cLswiEBqCQ@mail.gmail.com>

>
> Is this "inaccurate"? Well, in the sense that it is not the exact true
> mathematical result, yes it is, but that term can be misleading if you
> think of it as "a mistake". In another sense, it's not inaccurate, it is
> as accurate as possible (given the limitation of only having a certain
> fixed number of bits).
> --
> Steve
>

---
Understood about the quondam inexactness of floating point bit
representation. I was just wondering why the different implementation of
representing it when using Fraction(float) as opposed to using
Fraction(string(float)).  In terms of user presentation, the string usage
has smaller numbers for the ratio, so it would be more understandable and
should, I assume, be chosen for GUI display.
-- 
Jim

The Paleo diet causes Albinism

From alan.gauld at btinternet.com  Thu Apr 16 23:03:48 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 16 Apr 2015 22:03:48 +0100
Subject: [Tutor] How (not!) lengthy should functions be?
In-Reply-To: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
Message-ID: <mgp83i$vpk$1@ger.gmane.org>

On 16/04/15 17:47, boB Stepp wrote:

> things too far? For instance I have a collection of functions that do
> simple units conversions such as:
>
> def percent2Gy(dose_percent, target_dose_cGy):
>     """
>     Convert a dose given as a percent of target dose into Gy (Gray).
>     """
>     dose_Gy = cGy2Gy((dose_percent / 100.0) * target_dose_cGy)
>     return dose_Gy

I tend to draw the line at single liners like the above because by 
introducing the function you are increasing the complexity of the 
program. However, very often this kind of thing is justified if:
1) it aids unit testing
2) it makes the code significantly more readable
3) You perform error detection or validation of parameters.

Note in this case you could just create an alias

percent2GY = cGy2Gy

although you then need to do the math when you call it
rather than inside the function.

> My current understanding of function length best practice is that: 1)
> Each function should have preferably ONE clearly defined purpose.

By far the most important criteria. It trounces all other arguments.

2) I have seen varying recommendations as to number of lines of code

Most of these come from the days when we worked on dumb terminals with 
24 line screens. Actual measurements has shown that function length 
(within reason!) is not a major factor in comprehension or reliability. 
In COBOL or C it is not unreasonable to have functions over 50 lines 
long, sometimes over a hundred. But in Python that would be very 
unusual. So I'd treat the advise to limit length to about 20 lines of 
executable code to still be valid, if you exceed it treat it as a red 
flag to check that you really need it to be that long.

But splitting a function just to keep the line count down is a
terrible idea and more likely to introduce bugs than fix them.
The single purpose rule is the guide.

> equally well to methods.

In practice methods are usually a little bit shorter on average.
That's mainly because the data tends to live in object attributes
and be pre-formed, whereas a non method often spends significant
time reformatting input to the best shape for the function. Also
the object attributes were hopefully validated on creation so
each method can trust them, again saving lines.

> Am I on-track or am I getting carried away?

Probably on track.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From wolfgang.maier at biologie.uni-freiburg.de  Thu Apr 16 23:04:36 2015
From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier)
Date: Thu, 16 Apr 2015 23:04:36 +0200
Subject: [Tutor] Fraction - differing interpretations for number and
 string - presentation
In-Reply-To: <CALRAYNXb-cdhhob5GnCp2uRq5fqd_PkxvskEsBR2cLswiEBqCQ@mail.gmail.com>
References: <CALRAYNXb-cdhhob5GnCp2uRq5fqd_PkxvskEsBR2cLswiEBqCQ@mail.gmail.com>
Message-ID: <mgp854$vga$1@ger.gmane.org>

On 16.04.2015 19:24, Jim Mooney wrote:
>
> Understood about the quondam inexactness of floating point bit
> representation. I was just wondering why the different implementation of
> representing it when using Fraction(float) as opposed to using
> Fraction(string(float)).  In terms of user presentation, the string usage
> has smaller numbers for the ratio, so it would be more understandable and
> should, I assume, be chosen for GUI display.
>

The whole point of the discussion is that this is *not* a presentation 
issue. Fraction(1.64) and Fraction("1.64") *are* two different numbers 
because one gets constructed from a value that is not quite 1.64.
What sense would it make for Fraction(1.64) to represent itself inexactly ?
However, if you really want a shortened, but inexact answer: Fractions 
have a limit_denominator method that you could use like so:

 >>> Fraction(1.64).limit_denominator(25)
Fraction(41, 25)



From danny.yoo at gmail.com  Thu Apr 16 23:14:44 2015
From: danny.yoo at gmail.com (Danny Yoo)
Date: Thu, 16 Apr 2015 14:14:44 -0700
Subject: [Tutor] Fraction - differing interpretations for number and
 string - presentation
In-Reply-To: <CALRAYNXb-cdhhob5GnCp2uRq5fqd_PkxvskEsBR2cLswiEBqCQ@mail.gmail.com>
References: <CALRAYNXb-cdhhob5GnCp2uRq5fqd_PkxvskEsBR2cLswiEBqCQ@mail.gmail.com>
Message-ID: <CAGZAPF7ZL=HOXe-CcuYCn=15M7-rZ46=Nx+AapZ2915WaNC7rQ@mail.gmail.com>

On Apr 16, 2015 1:42 PM, "Jim Mooney" <cybervigilante at gmail.com> wrote:

> Understood about the quondam inexactness of floating point bit
> representation. I was just wondering why the different implementation of
> representing it when using Fraction(float) as opposed to using
> Fraction(string(float)).

Ah.  Correction.  You want to say: .. using Fraction(float) as opposed to
using
Fraction(**string**).

From breamoreboy at yahoo.co.uk  Fri Apr 17 00:24:37 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Thu, 16 Apr 2015 23:24:37 +0100
Subject: [Tutor] How (not!) lengthy should functions be?
In-Reply-To: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
Message-ID: <mgpcrb$egu$1@ger.gmane.org>

On 16/04/2015 17:47, boB Stepp wrote:
> As I go through my current coding project(s) I find myself breaking
> functions down into other functions, especially when I see see
> (unnecessarily) duplicated code fragments. I understand this to be
> regarded as good practice. However, I am wondering if I am carrying
> things too far? For instance I have a collection of functions that do
> simple units conversions such as:
>
> def percent2Gy(dose_percent, target_dose_cGy):
>     """
>     Convert a dose given as a percent of target dose into Gy (Gray).
>     """
>     dose_Gy = cGy2Gy((dose_percent / 100.0) * target_dose_cGy)
>     return dose_Gy

Slight aside, I'd not bother with the dose_Gy, simply:-

return cGy2Gy((dose_percent / 100.0) * target_dose_cGy)

but see also my comment at the end about aliases.

>
> This function calls another units conversion function, cGy2Gy(), in
> doing its work. Generally speaking, I have units conversions functions
> for every conversion I currently need to do plus some that I am not
> using yet because I can easily see the need for them in the future.
>
> My current understanding of function length best practice is that: 1)
> Each function should have preferably ONE clearly defined purpose. 2) I
> have seen varying recommendations as to number of lines of code per
> function, but I have seem multiple recommendations that a function
> generally should fit into one screen on one's monitor. Of course, some
> people have HUGE monitors! And I assume that any guidance applies
> equally well to methods.
>
> Am I on-track or am I getting carried away?
>

I'd say pretty much spot on, especially if you take Alan's advice and 
use aliases instead of the one line functions.  I can only assume that 
you've seen this quote "Always code as if the person who ends up 
maintaining your code is a violent psychopath who knows where you live."

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From davea at davea.name  Fri Apr 17 00:31:50 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 16 Apr 2015 18:31:50 -0400
Subject: [Tutor] Fraction - differing interpretations for number and
 string - presentation
In-Reply-To: <CALRAYNXb-cdhhob5GnCp2uRq5fqd_PkxvskEsBR2cLswiEBqCQ@mail.gmail.com>
References: <CALRAYNXb-cdhhob5GnCp2uRq5fqd_PkxvskEsBR2cLswiEBqCQ@mail.gmail.com>
Message-ID: <55303856.3030105@davea.name>

On 04/16/2015 01:24 PM, Jim Mooney wrote:
>>
>> Is this "inaccurate"? Well, in the sense that it is not the exact true
>> mathematical result, yes it is, but that term can be misleading if you
>> think of it as "a mistake". In another sense, it's not inaccurate, it is
>> as accurate as possible (given the limitation of only having a certain
>> fixed number of bits).
>> --
>> Steve
>>
>
> ---
> Understood about the quondam inexactness of floating point bit
> representation. I was just wondering why the different implementation of
> representing it when using Fraction(float) as opposed to using
> Fraction(string(float)).

You didn't use str(float), you used a simple str.  So there was no 
quantization error since it was never converted to binary floating 
point.  If you have a number that happens to be an exact decimal number, 
don't convert it via float().  Either convert it via Decimal() or 
convert it directly to fraction.


   In terms of user presentation, the string usage
> has smaller numbers for the ratio, so it would be more understandable and
> should, I assume, be chosen for GUI display.
>

Presumably you didn't read my message.  When you use a literal 1.64 in 
your code, you're telling the compiler to call the float() function on 
the token.  You've already forced the quantization error.  Nothing to do 
with the fraction class.

-- 
DaveA

From cybervigilante at gmail.com  Fri Apr 17 00:11:59 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Thu, 16 Apr 2015 15:11:59 -0700
Subject: [Tutor] Fraction - differing interpretations for number and
 string - presentation
In-Reply-To: <mgp854$vga$1@ger.gmane.org>
References: <CALRAYNXb-cdhhob5GnCp2uRq5fqd_PkxvskEsBR2cLswiEBqCQ@mail.gmail.com>
 <mgp854$vga$1@ger.gmane.org>
Message-ID: <CALRAYNVCGVb4Qp_6OB=00Wxx5+T9oz+H4MMgSBBwwMgUbaTHgQ@mail.gmail.com>

 The whole point of the discussion is that this is *not* a presentation
issue. Fraction(1.64) and Fraction("1.64") *are* two different numbers
because one gets constructed from a value that is not quite 1.64.

Wolfgang Maier
--
So the longer numerator and denominator would, indeed, be more accurate if
used in certain calculations rather than being normalized to a float - such
as in a Fortran subroutine or perhaps if exported to a machine with a
longer bit-length? That's mainly what I was interested in - if there is any
usable difference between the two results.

Jim

The Paleo diet causes Albinism

From alan.gauld at btinternet.com  Fri Apr 17 00:40:09 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 16 Apr 2015 23:40:09 +0100
Subject: [Tutor] How (not!) lengthy should functions be?
In-Reply-To: <mgp83i$vpk$1@ger.gmane.org>
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
 <mgp83i$vpk$1@ger.gmane.org>
Message-ID: <mgpdo7$sv2$1@ger.gmane.org>

On 16/04/15 22:03, Alan Gauld wrote:

>> def percent2Gy(dose_percent, target_dose_cGy):
>>     """
>>     Convert a dose given as a percent of target dose into Gy (Gray).
>>     """
>>     dose_Gy = cGy2Gy((dose_percent / 100.0) * target_dose_cGy)
>>     return dose_Gy
>

> Note in this case you could just create an alias
>
> percent2GY = cGy2Gy

Except that the name would then be misleading - my bad!
The value that your function adds is the percentage calculation.

But if it is a straight renaming exercise then an alias would
be more appropriate than defining a new wrapper function.

Sorry, for the bad example.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From breamoreboy at yahoo.co.uk  Fri Apr 17 01:04:45 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Fri, 17 Apr 2015 00:04:45 +0100
Subject: [Tutor] How (not!) lengthy should functions be?
In-Reply-To: <mgpdo7$sv2$1@ger.gmane.org>
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
 <mgp83i$vpk$1@ger.gmane.org> <mgpdo7$sv2$1@ger.gmane.org>
Message-ID: <mgpf6i$k8e$1@ger.gmane.org>

On 16/04/2015 23:40, Alan Gauld wrote:
> On 16/04/15 22:03, Alan Gauld wrote:
>
>>> def percent2Gy(dose_percent, target_dose_cGy):
>>>     """
>>>     Convert a dose given as a percent of target dose into Gy (Gray).
>>>     """
>>>     dose_Gy = cGy2Gy((dose_percent / 100.0) * target_dose_cGy)
>>>     return dose_Gy
>>
>
>> Note in this case you could just create an alias
>>
>> percent2GY = cGy2Gy
>
> Except that the name would then be misleading - my bad!
> The value that your function adds is the percentage calculation.
>
> But if it is a straight renaming exercise then an alias would
> be more appropriate than defining a new wrapper function.
>
> Sorry, for the bad example.
>

Bah, that'll teach me to read more closely in the future :(

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From steve at pearwood.info  Fri Apr 17 04:29:10 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 17 Apr 2015 12:29:10 +1000
Subject: [Tutor] Fraction - differing interpretations for number and
	string - presentation
In-Reply-To: <CALRAYNVCGVb4Qp_6OB=00Wxx5+T9oz+H4MMgSBBwwMgUbaTHgQ@mail.gmail.com>
References: <CALRAYNXb-cdhhob5GnCp2uRq5fqd_PkxvskEsBR2cLswiEBqCQ@mail.gmail.com>
 <mgp854$vga$1@ger.gmane.org>
 <CALRAYNVCGVb4Qp_6OB=00Wxx5+T9oz+H4MMgSBBwwMgUbaTHgQ@mail.gmail.com>
Message-ID: <20150417022910.GS5663@ando.pearwood.info>

On Thu, Apr 16, 2015 at 03:11:59PM -0700, Jim Mooney wrote:

> So the longer numerator and denominator would, indeed, be more accurate if
> used in certain calculations rather than being normalized to a float - such
> as in a Fortran subroutine or perhaps if exported to a machine with a
> longer bit-length? That's mainly what I was interested in - if there is any
> usable difference between the two results.

You're asking simple questions that have complicated answers which 
probably won't be what you are looking for. But let's try :-)

Let's calculate a number. The details don't matter:

x = some_calculation(a, b)
print(x)

which prints 1.64. Great, we have a number that is the closest possible 
base 2 float to the decimal 164/100. If we convert that float to a 
fraction *exactly*, we get:

py> Fraction(1.64)
Fraction(7385903388887613, 4503599627370496)

So the binary float which displays as 1.64 is *actually* equal to 
7385903388887613/4503599627370496, which is just a tiny bit less than 
the decimal 1.64:

py> Fraction(1.64) - Fraction("1.64")
Fraction(-11, 112589990684262400)

That's pretty close. The decimal value that normally displays as 1.64 is 
perhaps more accurately displayed as:

py> "%.23f" % 1.64
'1.63999999999999990230037'

but even that is not exact.

So which is the "right" answer? That depends.

(1) It could be that our initial calculation some_calculation(a, b) 
actually was 164/100, say, in which case the *correct* result should be 
decimal 1.64 = Fraction("1.64") and the 7385blahblahblah/blahblahblah is 
just an artifact of the fact that floats are binary.

(2) Or it could be that the some_calculation(a, b) result actually was
7385903388887613/4503599627370496, say, in which case it is a mere 
coincidence that this number displays as 1.64 when treated as a binary 
float. The long 7385blahblahblah numerator and denominator is exactly 
correct, and decimal 1.64 is a approximation.

There is no way of telling in advance which interpretation is correct. 
You need to think about the calculation you performed and decide what it 
means, not just look at the final result.

Although... 9 times out of 10, if you get something *close* to an exact 
decimal, a coincidence is not likely. If you get exactly 0.5 out of a 
calculation, rather than 0.5000000000001, then it probably should be 
exactly 1/2. *Probably*. The reality is that very often, the difference 
isn't that important. The difference between

1.64 inches

and

1.63999999999999990230037 inches

is probably not going to matter, especially if you are cutting the 
timber with a chainsaw.



-- 
Steve

From robertvstepp at gmail.com  Fri Apr 17 15:26:38 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 17 Apr 2015 08:26:38 -0500
Subject: [Tutor] How to print ALL contents of a scrolled Tkinter window?
Message-ID: <CANDiX9+qVEJ6Ph8V8VSTGnC6wu1F6ME4t1GqvwnoO4dEcKqmNA@mail.gmail.com>

Solaris 10, Python 2.4.4

Thanks to earlier help from this list, I can now print a particular
Tkinter-generated window. But this will only print what is currently
viewable on the screen. In the case of scrolled information that is
currently outside the viewing area, it would be missed by such a print
(Using OS import command, as Peter demonstrated.). This type of print
functionality appears in everyday software products, but it is not
clear to me (Yet!) how to approach this problem. My initial thoughts
are along the lines of: 1) Determine how many rows of information
appear in the viewing area. 2) Determine how many total rows of
information exist to be printed. 3) Figure out how to programmatically
do a *manual* scroll to bring up the hidden scrolled information. 4)
Repeatedly apply the printing method. While I can probably make this
approach work (It *seems* conceptually simple.), I cannot help but
feel there is a much better way...

I intend to scour my available Tkinter documentation to see if there
are root window level and scrolled area commands that might suggest
another approach. And what I am doing now, seeking your collective
wisdom...

Thanks!

-- 
boB

From oscar.j.benjamin at gmail.com  Fri Apr 17 16:02:41 2015
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Fri, 17 Apr 2015 15:02:41 +0100
Subject: [Tutor] Fraction - differing interpretations for number and
 string - presentation
In-Reply-To: <20150417022910.GS5663@ando.pearwood.info>
References: <CALRAYNXb-cdhhob5GnCp2uRq5fqd_PkxvskEsBR2cLswiEBqCQ@mail.gmail.com>
 <mgp854$vga$1@ger.gmane.org>
 <CALRAYNVCGVb4Qp_6OB=00Wxx5+T9oz+H4MMgSBBwwMgUbaTHgQ@mail.gmail.com>
 <20150417022910.GS5663@ando.pearwood.info>
Message-ID: <CAHVvXxRuihUdc779pY-iVMB2qsJM=4YBpbqvz-UmgdsGReBEfQ@mail.gmail.com>

On 17 April 2015 at 03:29, Steven D'Aprano <steve at pearwood.info> wrote:
> On Thu, Apr 16, 2015 at 03:11:59PM -0700, Jim Mooney wrote:
>
>> So the longer numerator and denominator would, indeed, be more accurate if
>> used in certain calculations rather than being normalized to a float - such
>> as in a Fortran subroutine or perhaps if exported to a machine with a
>> longer bit-length? That's mainly what I was interested in - if there is any
>> usable difference between the two results.

If it's okay to use float and then go onto machines with higher/lower
precision then the extra precision must be unnecessary in which case
why bother with the Fraction type? If you really need to transfer your
float from one program/machine to another then why not just send the
decimal representation. Your 64-bit float should be able to round-trip
to decimal text and back for any IEEE-754 compliant systems. Writing
it as a fraction doesn't gain any extra accuracy. (BTW Python the
language guarantees that float is always an IEEE-754 64-bit float on
any machine).

When you use floats the idea is that you're using fixed-width floating
point as an approximation of real numbers. You're expected to know
that there will be some rounding and not consider your computation to
be exact. So the difference between 1.64 and the nearest IEEE-754
64-bit binary float should be considered small enough not to worry
about.

It's possible that in your calculations you will also be using
functions from the math module such as sin, cos, etc. and these
functions cannot be computed *exactly* for an input such as 1.64.
However they can be computed up to any desired finite precision so we
can always get the nearest possible float which is what the math
module will do.

When you use the fractions module and the Fraction type the idea is
that floating point inexactness is unacceptable to you. You want to
perform *exact* arithmetic and convert from other numeric types or
text exactly. You won't be able to use functions like sin and cos but
that's no loss since you wouldn't be able to get an exact rational
result there anyway.

Because the Fractions module is designed for the "I want everything to
be exact" use case conversion from float to Fraction is performed
exactly. Conversion from string or Decimal to Fraction is also exact.
The Fraction will also display its exact value when printed and that's
what you're seeing.

If you really want higher accuracy than float consider ditching it
altogether in favour of Fraction which will compute everything you
want exactly. However there's no point in doing this if you're also
mixing floats into the calculations. float+Fraction coerces to float
discarding accuracy and then calculates with floating point rounding.
If that's acceptable then don't bother with Fraction in the first
place. If not make sure you stick to only using Fraction.

> You're asking simple questions that have complicated answers which
> probably won't be what you are looking for. But let's try :-)
>
> Let's calculate a number. The details don't matter:
>
> x = some_calculation(a, b)
> print(x)
>
> which prints 1.64. Great, we have a number that is the closest possible
> base 2 float to the decimal 164/100. If we convert that float to a
> fraction *exactly*, we get:
>
> py> Fraction(1.64)
> Fraction(7385903388887613, 4503599627370496)
>
> So the binary float which displays as 1.64 is *actually* equal to
> 7385903388887613/4503599627370496, which is just a tiny bit less than
> the decimal 1.64:
>
> py> Fraction(1.64) - Fraction("1.64")
> Fraction(-11, 112589990684262400)
>
> That's pretty close. The decimal value that normally displays as 1.64 is
> perhaps more accurately displayed as:
>
> py> "%.23f" % 1.64
> '1.63999999999999990230037'
>
> but even that is not exact.

Just to add to Steven's point. The easiest way to see the exact value
of a float in decimal format is:
>>> import decimal
>>> decimal.Decimal(1.64)
Decimal('1.6399999999999999023003738329862244427204132080078125')

> The reality is that very often, the difference
> isn't that important. The difference between
>
> 1.64 inches
>
> and
>
> 1.63999999999999990230037 inches
>
> is probably not going to matter, especially if you are cutting the
> timber with a chainsaw.

I once had a job surveying a building site as an engineer's assistant.
I'd be holding a reflector stick while he operated the laser sight
machine (EDM) from some distance away and spoke to me over the radio.
He'd say "mark it 10mm to the left". The marker spray would make a
circle that was about 100mm in diameter. Then I would get 4 unevenly
shaped stones (that happened to be lying around) and drop them on the
ground to mark out the corners of a 1500mm rectangle by eye.
Afterwards the excavator would dig a hole there using a bucket that
was about 1000mm wide. While digging the stones would get moved around
and the operator would end up just vaguely guessing where the original
marks had been.

The engineer was absolutely insistent that it had to be 10mm to the
left though. I think that just naturally happens when you're equipment
is more accurate than it needs to be for the task in hand.


Oscar

From robertvstepp at gmail.com  Fri Apr 17 17:05:10 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 17 Apr 2015 10:05:10 -0500
Subject: [Tutor] How to print ALL contents of a scrolled Tkinter window?
In-Reply-To: <201504171429.t3HETlaG010853@fido.openend.se>
References: <robertvstepp@gmail.com>
 <CANDiX9+qVEJ6Ph8V8VSTGnC6wu1F6ME4t1GqvwnoO4dEcKqmNA@mail.gmail.com>
 <201504171429.t3HETlaG010853@fido.openend.se>
Message-ID: <CANDiX9+aWERQcFHe=_HvrmwiFwF+ppHA3xMLsoFCz+imi__Ymg@mail.gmail.com>

On Fri, Apr 17, 2015 at 9:29 AM, Laura Creighton <lac at openend.se> wrote:
>>While I can probably make this
>>approach work (It *seems* conceptually simple.), I cannot help but
>>feel there is a much better way...
>
> Tkinter is very old software.  This sort of scrolling you want was
> in no way common when Tkinter was new.  For things like this, I
> just use kivy, which has the advantage that is runs under IOS and
> Android out of the box.
>
> The whole point of kivy is to create better, new paradigm user interfaces,
> where scrolling surfaces are built-in.
>
> It may be faster for you to reimplement what you have in kivy than to
> try to get Tkinter to do what you want.

Alas! I am not allowed to install any new software on these systems
(Which use Python 2.4.4 or 2.6.4.). So I am stuck with whatever tools
are installed by default, and that does not include your suggestion.
However, I will look into kivy for my at-home studies/projects!


-- 
boB

From lac at openend.se  Fri Apr 17 16:29:47 2015
From: lac at openend.se (Laura Creighton)
Date: Fri, 17 Apr 2015 16:29:47 +0200
Subject: [Tutor] How to print ALL contents of a scrolled Tkinter window?
In-Reply-To: Message from boB Stepp <robertvstepp@gmail.com> of "Fri,
 17 Apr 2015 08:26:38 -0500."
 <CANDiX9+qVEJ6Ph8V8VSTGnC6wu1F6ME4t1GqvwnoO4dEcKqmNA@mail.gmail.com>
References: <CANDiX9+qVEJ6Ph8V8VSTGnC6wu1F6ME4t1GqvwnoO4dEcKqmNA@mail.gmail.com>
Message-ID: <201504171429.t3HETlaG010853@fido.openend.se>

>While I can probably make this
>approach work (It *seems* conceptually simple.), I cannot help but
>feel there is a much better way...

Tkinter is very old software.  This sort of scrolling you want was
in no way common when Tkinter was new.  For things like this, I
just use kivy, which has the advantage that is runs under IOS and
Android out of the box.

The whole point of kivy is to create better, new paradigm user interfaces,
where scrolling surfaces are built-in.

It may be faster for you to reimplement what you have in kivy than to
try to get Tkinter to do what you want.

Laura

From niyanaxx95 at gmail.com  Fri Apr 17 20:11:00 2015
From: niyanaxx95 at gmail.com (niyanaxx95 at gmail.com)
Date: Fri, 17 Apr 2015 18:11:00 +0000
Subject: [Tutor] =?utf-8?q?=3DLinked_List_Using_Map?=
In-Reply-To: <55314ca1.c7628c0a.6f1c.ffffd77a@mx.google.com>
References: <55314ca1.c7628c0a.6f1c.ffffd77a@mx.google.com>
Message-ID: <55314cc2.9512370a.1868.ffffd2c5@mx.google.com>








Sent from Windows Mail





From: Ni'Yana Morgan
Sent: ?Friday?, ?April? ?17?, ?2015 ?2?:?06? ?PM
To: tutors at python.org





Hello I need guidance trying to solve my assignment. I am completely lost when using maps with linked lists. I understand linked lists though. May someone work with me?








implement the Map ADT using a singly linked list:


? Map(): Creates a new empty map.

? length(): Returns the number of key/value pairs in the map.

? contains(key): Returns a Boolean indicating if the given key is in the map.

? setitem(key, value): Adds a new key/value pair to the map if the key is not in the map. If the key is in the map, the new value replaces the original value associated with the key. 

? getitem(key): Returns the value associated with the given key, which must exist. 

? clear(): Clears or empties the map by removing all key/value pairs. 

? keys(): Returns a list containing the keys stored in the map. 

? values(): Returns a list containing the values stored in the map. 

? toString(): Returns a string representation of the map in the following format: {k1:v1, k2:v2, ..., kN:vN} 

? min(): Returns the minimum key in the map. The map can not be empty. 

? max(): Returns the maximum key in the map. The map can not be empty. 

? copy(): Creates and returns a new map that is a duplicate copy of this map.




My Code (so far):

class Node:
    def __init__( self, item, next = None ) :
        self.item = item
        self.next = next
    
    def getItem( self ) :
        return self.item
    
    def getNext( self ) :
        return self.next
    
    def setItem( self, item ) :
        self.item = item
        
    def setNext( self, next ) :
        self.next = next




class Map:
    
    def __init__( self, contents = []) :
        self.first = LinkedList.Node(None, None)
        self.last = self.first
        self.numItems = 0
        
        for e in contents:
            self.append(e)
            
    def __len__( self ) :
        count = 0
        while self != None:
            count +=1
            self = self.next
        return count
    
    def contains() :
        pass
    
    def __setitem__( self, index, value ) :
        if index >= 0 and index < self.numItems:
            cursor = self.first.getNext()
            for i in range( index ):
                cursor = cursor.getNext()
            return cursor.getItem()
    
    def __getitem__( self, index, value ) :
        if index >= 0 and index < self.numItems:
            cursor = self.first.getNext()
            for i in range( index ):
                cursor = cursor.getNext()
            cursor.setItem( value )
            return

From samuel.viscapi at univ-montp2.fr  Fri Apr 17 10:39:01 2015
From: samuel.viscapi at univ-montp2.fr (Samuel VISCAPI)
Date: Fri, 17 Apr 2015 10:39:01 +0200
Subject: [Tutor] Unicode encoding and raw_input() in Python 2.7 ?
Message-ID: <5530C6A5.7010808@univ-montp2.fr>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hi,

This is my first post to that mailing list if I remember correctly, so
hello everyone !

I've been stuck on a simple problem for the past few hours. I'd just
like raw_input to work with accentuated characters.

For example:

firstname = str.capitalize(raw_input('First name: '))

where firstname could be "Val?rie", "Gis?le", "Honor?", etc...

I tried -*- coding: utf-8 -*-, u'', unicode(), but to no avail...

I'm using str.capitalize and str.lower throughout my code, so I guess
some encoding / decoding will also be necessary at some point.

Thanks a lot for your help !

Cheers, Samuel



-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (GNU/Linux)

iF4EAREIAAYFAlUwxqUACgkQqjnQbvs+kDn4AAD/YHz55tvBixTgdp16L45tc8Dr
/0jyPNg9aMndpwoDlLkA/2SnSWLkeSwI4xM9xKbucx+28I50NcEG/8wx8c31GWll
=KI8s
-----END PGP SIGNATURE-----

From alan.gauld at btinternet.com  Fri Apr 17 21:28:21 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 17 Apr 2015 20:28:21 +0100
Subject: [Tutor] How to print ALL contents of a scrolled Tkinter window?
In-Reply-To: <CANDiX9+qVEJ6Ph8V8VSTGnC6wu1F6ME4t1GqvwnoO4dEcKqmNA@mail.gmail.com>
References: <CANDiX9+qVEJ6Ph8V8VSTGnC6wu1F6ME4t1GqvwnoO4dEcKqmNA@mail.gmail.com>
Message-ID: <mgrmsj$ohl$1@ger.gmane.org>

On 17/04/15 14:26, boB Stepp wrote:
> Solaris 10, Python 2.4.4
>
> Thanks to earlier help from this list, I can now print a particular
> Tkinter-generated window. But this will only print what is currently
> viewable on the screen.

Because it is effectively taking a screen shot.

> In the case of scrolled information that is
> currently outside the viewing area, it would be missed by such a print

That's why GUI printing generally uses an entirely different
technique to print things (see my earlier email). In essence
this requires you to separate the data content and format
from the GUI presentation. The printed presentation must be
prepared by you the programmer and output to the new display
context(a printer). This means you need to decide how to
handle page breaks, page width and orientation etc etc.

Its a whole different ballgame and much more complex than
simply issuing a print command. Hard copy output from a
GUI is one of the hardest things to do in almost any GUI,
especially if you want it truly WYSIWYG.

My personal favourite approach is to abandon WYSIWYG and
go for WYSRWYG - What you see resembles what you'll get...
And then I reformat the data using HTML, send it to a file
and print that file using whatever HTML rendering engine
I can find.

wxPython makes printing easier but even there its a
whole chapter(ch17) of the book and its at the end so
assumes you already know all the background around sizers,
device context and the like.... The example program - for
printing a formatted text document - runs to 2.5 pages of
code. And that's the easiest printing framework I've seen.

> are along the lines of: 1) Determine how many rows of information
> appear in the viewing area. 2) Determine how many total rows of
> information exist to be printed. 3) Figure out how to programmatically
> do a *manual* scroll to bring up the hidden scrolled information. 4)
> Repeatedly apply the printing method. While I can probably make this
> approach work (It *seems* conceptually simple.), I cannot help but
> feel there is a much better way...

Its never going to be pretty but multiple screen captures
can work. Its certainly easy enough to reposition a scroll
bar programmatically from within a while loop. Figuring out
how many lines will depend on all sorts of things like
the size of fonts being used, how widgets are laid out.
That's what gets tricky, especially if users don't have
standardised screen sizes etc.

> I intend to scour my available Tkinter documentation to see if there
> are root window level and scrolled area commands that might suggest
> another approach.

Not really. Tkinter (and Tk) basically sidesteps printing
to hard copy. There simply is no built in support. You have
to format it yourself.

Check out IDLE - even it doesn't have any built in
formatted print. It only has 'Print Window', which is
just plain text.
Although even looking at how they did that might
help too. Remember you have the code to IDLE and
its built using Tkinter...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Fri Apr 17 21:45:38 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 17 Apr 2015 20:45:38 +0100
Subject: [Tutor] =Linked List Using Map
In-Reply-To: <55314cc2.9512370a.1868.ffffd2c5@mx.google.com>
References: <55314ca1.c7628c0a.6f1c.ffffd77a@mx.google.com>
 <55314cc2.9512370a.1868.ffffd2c5@mx.google.com>
Message-ID: <mgrnt0$9jl$1@ger.gmane.org>

On 17/04/15 19:11, niyanaxx95 at gmail.com wrote:

> Hello I need guidance trying to solve my assignment.
 > I am completely lost when using maps with linked lists.
 > I understand linked lists though.

Unfortunately we do not. Linked lists aren't really
a native Python type and maps are a native type - the
dictionary. So implementing the equivalent of a
native type using a non-native type is kind of a
bizarre situation.

Without knowing how your linked list is built we can't
tell you anything about how to build a map(dictionary)
from it.

> implement the Map ADT using a singly linked list:
> ? Map(): Creates a new empty map.
> ? length(): Returns the number of key/value pairs in the map.
> ? contains(key): Returns a Boolean indicating if the given key is in the map.
> ? setitem(key, value): Adds a new key/value pair to the map if the key is not in the map. If the key is in the map, the new value replaces the original value associated with the key.
> ? getitem(key): Returns the value associated with the given key, which must exist.
> ? clear(): Clears or empties the map by removing all key/value pairs.
> ? keys(): Returns a list containing the keys stored in the map.
> ? values(): Returns a list containing the values stored in the map.
> ? toString(): Returns a string representation of the map in the following format: {k1:v1, k2:v2, ..., kN:vN}
> ? min(): Returns the minimum key in the map. The map can not be empty.
> ? max(): Returns the maximum key in the map. The map can not be empty.
> ? copy(): Creates and returns a new map that is a duplicate copy of this map.

That's a pretty hefty API for an assignment of this type!

> My Code (so far):

I assume that your Node is in a separate file called LinkedList.py?

> class Node:
>      def __init__( self, item, next = None ) :
>          self.item = item
>          self.next = next
>
>      def getItem( self ) :
>          return self.item
>
>      def getNext( self ) :
>          return self.next
>
>      def setItem( self, item ) :
>          self.item = item
>
>      def setNext( self, next ) :
>          self.next = next

That all seems fairly normal.

> class Map:
>
>      def __init__( self, contents = []) :
>          self.first = LinkedList.Node(None, None)
>          self.last = self.first
>          self.numItems = 0
>
>          for e in contents:
>              self.append(e)

Where does append() come from? Its not a method of Map.


>      def __len__( self ) :
>          count = 0
>          while self != None:
>              count +=1
>              self = self.next
>          return count

Notice you were asked to provide a length() method so
presumably your __len__() operator should just call
self.length(). And if you update self.numItems
correctly isn't length() just returning self.numItems?

>      def contains() :
>          pass
>
>      def __setitem__( self, index, value ) :
>          if index >= 0 and index < self.numItems:
>              cursor = self.first.getNext()
>              for i in range( index ):
>                  cursor = cursor.getNext()
>              return cursor.getItem()

you seem to have the setItem and getItem actions reversed?

>
>      def __getitem__( self, index, value ) :
>          if index >= 0 and index < self.numItems:
>              cursor = self.first.getNext()
>              for i in range( index ):
>                  cursor = cursor.getNext()
>              cursor.setItem( value )
>              return

I suggest you go and have a think about how you will store the key/value 
pairs needed for a map in your list. Then think about
how you find a node by key. Then think about how to get the
value or set a new value on that node.

<rant>
I hate when teachers ask students to do stupid stuff like this.
It encourages so many bad practices it's positively dangerous!
If they must have them reinvent the wheel at least let them
use the native Python list to do it!
</rant>

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Fri Apr 17 21:58:10 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 17 Apr 2015 20:58:10 +0100
Subject: [Tutor] Unicode encoding and raw_input() in Python 2.7 ?
In-Reply-To: <5530C6A5.7010808@univ-montp2.fr>
References: <5530C6A5.7010808@univ-montp2.fr>
Message-ID: <mgrokg$lgg$1@ger.gmane.org>

On 17/04/15 09:39, Samuel VISCAPI wrote:
> hello everyone !

Hello, and welcome.

> I've been stuck on a simple problem for the past few hours. I'd just
> like raw_input to work with accentuated characters.
>
> For example:
>
> firstname = str.capitalize(raw_input('First name: '))
>
> where firstname could be "Val?rie", "Gis?le", "Honor?", etc...
>
> I tried -*- coding: utf-8 -*-, u'', unicode(), but to no avail...

You know what you tried. We don't so please post again showing
us some actual code that you tried and didn't work.
Tell us (or show us cut n pasted output) what you got and
what you expected.

Otherwise we are just guessing.

> I'm using str.capitalize and str.lower throughout my code, so I guess
> some encoding / decoding will also be necessary at some point.

capitalize/lower etc don't really care about encodings.
They just work with the string they are given.
I'm not sure what extra you think you will need to do.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Fri Apr 17 22:06:35 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 17 Apr 2015 21:06:35 +0100
Subject: [Tutor] How to print ALL contents of a scrolled Tkinter window?
In-Reply-To: <201504171429.t3HETlaG010853@fido.openend.se>
References: <CANDiX9+qVEJ6Ph8V8VSTGnC6wu1F6ME4t1GqvwnoO4dEcKqmNA@mail.gmail.com>
 <201504171429.t3HETlaG010853@fido.openend.se>
Message-ID: <mgrp4a$suq$1@ger.gmane.org>

On 17/04/15 15:29, Laura Creighton wrote:

> just use kivy, which has the advantage that is runs under IOS and
> Android out of the box.

But does Kivy support hard copy printing?
That's pretty unusual behaviour on
tablets/phones.

If so can you show us a short example of
how it works. (Technically off-topic for
the tutor list but I'm curious to see
how it compares to say, Tkinter)

> The whole point of kivy is to create better, new paradigm user interfaces,
> where scrolling surfaces are built-in.

That wouldn't be on mobile devices then,
where the UIs are universally horrible IMHO! :-)
They are the very antithesis of good user
interface design.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From davea at davea.name  Sat Apr 18 02:37:10 2015
From: davea at davea.name (Dave Angel)
Date: Fri, 17 Apr 2015 20:37:10 -0400
Subject: [Tutor] Unicode encoding and raw_input() in Python 2.7 ?
In-Reply-To: <5530C6A5.7010808@univ-montp2.fr>
References: <5530C6A5.7010808@univ-montp2.fr>
Message-ID: <5531A736.9010204@davea.name>

On 04/17/2015 04:39 AM, Samuel VISCAPI wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> Hi,
>
> This is my first post to that mailing list if I remember correctly, so
> hello everyone !
>

Welcome to the list.

> I've been stuck on a simple problem for the past few hours. I'd just
> like raw_input to work with accentuated characters.

That should mean you want to use unicode.


If you're using raw_input, then you must be using Python 2.x.  Easiest 
first step to doing things right in Unicode would be to switch to 
version 3.x    But I'll assume that you cannot do this, for the duration 
of this message.



>
> For example:
>
> firstname = str.capitalize(raw_input('First name: '))

If you're serious about Unicode, you're getting an encoded string with 
raw_input, so you'll need to decode it, using whatever encoding your 
console device is using.  If you don't know, you're in big trouble.  But 
if you're in Linux, chances are good that it's utf-8.

>
> where firstname could be "Val?rie", "Gis?le", "Honor?", etc...


>
> I tried -*- coding: utf-8 -*-, u'', unicode(), but to no avail...
>

As Alan says, you're not tellins us anything useful.  "No avail" is too 
imprecise to be useful.   I'll comment on them anyway.

The coding statement applies only to literals you use in your source 
code.  It has nothing at all to do with the value returned by raw_input.

u'' likewise is used in your source code.  It has nothing to do with 
what the user may type into your program.

unicode() is a "function" that may decode a string received from 
raw_input, providing you know what the coding was.  You can also 
accomplish it by using the method str.decode().


> I'm using str.capitalize and str.lower throughout my code, so I guess
> some encoding / decoding will also be necessary at some point.

Those apply to strings.  But if you're doing it right, you should have 
unicode objects long before you apply such methods.  So you'd want the 
unicode methods  unicode.upper and unicode.lower



-- 
DaveA

From wallenpb at gmail.com  Sat Apr 18 05:16:27 2015
From: wallenpb at gmail.com (Bill Allen)
Date: Fri, 17 Apr 2015 22:16:27 -0500
Subject: [Tutor] lists, name semantics
Message-ID: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>

If I have a list defined as my_list = ['a','b','c'], what is the is
differnce between refering to it as my_list or my_list[:]?   These seem
equivalent to me.  Is that the case?  Is there any nuance I am missing
here?   Situations where one form should be used as opposed to the other?

Thanks,
Bill Allen

From ben+python at benfinney.id.au  Sat Apr 18 05:27:55 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Sat, 18 Apr 2015 13:27:55 +1000
Subject: [Tutor] lists, name semantics
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
Message-ID: <85pp72qfno.fsf@benfinney.id.au>

Bill Allen <wallenpb at gmail.com> writes:

> If I have a list defined as my_list = ['a','b','c'], what is the is
> differnce between refering to it as my_list or my_list[:]?

?my_list? is a reference to the object you've already described (the
existing object ?['a', 'b', 'c']?).

?my_list[:]? is an operation that takes the original object and creates
a new one by slicing. In this case, the new object happens to be equal
to (but probably not identical to) the original, because of the slice
you specified.

> Is there any nuance I am missing here? Situations where one form
> should be used as opposed to the other?

You need to understand, when writing code, whether you are intending to
refer to the original object, or to create a new one. Neither is better,
they are both common but different operations.

-- 
 \          ?Our products just aren't engineered for security.? ?Brian |
  `\             Valentine, senior vice-president of Microsoft Windows |
_o__)                                                development, 2002 |
Ben Finney


From martin at linux-ip.net  Sat Apr 18 05:42:11 2015
From: martin at linux-ip.net (Martin A. Brown)
Date: Fri, 17 Apr 2015 20:42:11 -0700
Subject: [Tutor] lists, name semantics
In-Reply-To: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
Message-ID: <alpine.LSU.2.11.1504172022280.31213@znpeba>


Good evening Bill,

> If I have a list defined as my_list = ['a','b','c'], what is the 
> is differnce between refering to it as my_list or my_list[:]? 
> These seem equivalent to me.  Is that the case?  Is there any 
> nuance I am missing here?  Situations where one form should be 
> used as opposed to the other?

Yes, there is a difference.  It can (conceivably) by subtle, but it 
is simple.

Let's start with the following.  I will call the list by the 
variable name l.  So, Python ('the computer') has stored the list in 
memory.  After executing this command, if I want to retrieve that 
data, I can call it by the variable named 'l':

   l = ['a', 'b', 'c']

Now consider the following two statements.

   case A:    k = l
   case B:    m = l[:]

These perform two different operations.  The first simply says "Hey, 
when I refer to variable k, I want it to behave exactly like I had 
used the variable named l."  The second says "Please give me a COPY 
of everything contained in the variable named l and let me refer to 
that as the variable named m."

What is the nuance of difference?  Where are the data stored in 
memory?  Let's take case A:

   >>> l = ['a', 'b', 'c']
   >>> k = l
   >>> k == l
   True
   >>> k is l
   True

So, you see, not only are k and l refer to the same list contents, 
but they point to the same place in computer memory where the list 
is stored.  The variables named l and k are just different names for 
the same thing (data).

Now, let's see what happens when we use case B, copying the list 
(strictly speaking you are slicing the entire list, see Python 
documentation).

   >>> m = l[:]
   >>> m == l
   True
   >>> m is l
   False

What's different here?  Well, the variables m and l have the same 
contents, and are therefore equal (this will compare all elements of 
the list for equality).  But, m and l are not the same thing (data)! 
Though they contain the same data, the list contents are stored in 
different places in computer memory.

This subtlety means that you probably do not want to say my_list[:] 
unless you really want to use up all the memory to store the same 
data twice.  You may wish to do that, but given your question about 
nuance, I would point out that this is no nuance but a significant 
feature which can surprise you later if you do not understand what 
is happening with the slicing notation.

Best of luck and enjoy a fried slice of Python!

-Martin

  [0] https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range

-- 
Martin A. Brown
http://linux-ip.net/

From ben+python at benfinney.id.au  Sat Apr 18 05:51:05 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Sat, 18 Apr 2015 13:51:05 +1000
Subject: [Tutor] lists, name semantics
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <85pp72qfno.fsf@benfinney.id.au>
Message-ID: <85iocuqel2.fsf@benfinney.id.au>

Ben Finney <ben+python at benfinney.id.au> writes:

> Bill Allen <wallenpb at gmail.com> writes:
>
> > If I have a list defined as my_list = ['a','b','c'], what is the is
> > differnce between refering to it as my_list or my_list[:]?
>
> ?my_list? is a reference to the object you've already described (the
> existing object ?['a', 'b', 'c']?).
>
> ?my_list[:]? is an operation that takes the original object and
> creates a new one by slicing. In this case, the new object happens to
> be equal to (but probably not identical to) the original, because of
> the slice you specified.

To demonstrate how identity differs from equality, use the appropriate
comparison operators::

    $ python3

    >>> foo = ['a', 'b', 'c']

    >>> bar = foo     # Bind the name ?bar? to the same object.
    >>> bar           # Show me the object referred to by ?bar?.
    ['a', 'b', 'c']
    >>> bar == foo    # Is the object ?bar? equal to the object ?foo??
    True
    >>> bar is foo    # Is ?bar? referring to the same object as ?foo??
    True

    >>> baz = foo[:]  # Slice ?foo?, creating a new list; bind ?baz? to that.
    >>> baz           # Show me the object referred to by ?baz?.
    ['a', 'b', 'c']
    >>> baz == foo    # Is the object ?baz? equal to the object ?foo??
    True
    >>> baz is foo    # Is ?baz? referring to the same object as ?foo??
    False

References which compare identical *are the same* object, guaranteed.
Object identity almost always implies equality.

(?almost always? because some object types have unusual behaviour like
?the object is not equal to itself?. Don't fret about that though, these
exceptions are clearly defined when you find them.)


References which compare equal *may under some conditions* be identical.
This is *not* ever a promise, though, and you should never rely on it,
not even in the same session of a program.

Some of Python's internal optimisations depend on the fact that object
equality *does not* imply object identity. If you happen to notice some
operations producing the same object at one point in time, but the
documentation doesn't promise it, then treat that as an unpredictable
implementation detail and don't rely on it in your code.

-- 
 \       ?The best in us does not require the worst in us: Our love of |
  `\     other human beings does not need to be nurtured by delusion.? |
_o__)                             ?Sam Harris, at _Beyond Belief 2006_ |
Ben Finney


From davea at davea.name  Sat Apr 18 07:03:34 2015
From: davea at davea.name (Dave Angel)
Date: Sat, 18 Apr 2015 01:03:34 -0400
Subject: [Tutor] lists, name semantics
In-Reply-To: <85iocuqel2.fsf@benfinney.id.au>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <85pp72qfno.fsf@benfinney.id.au> <85iocuqel2.fsf@benfinney.id.au>
Message-ID: <5531E5A6.1000601@davea.name>

On 04/17/2015 11:51 PM, Ben Finney wrote:
> Ben Finney <ben+python at benfinney.id.au> writes:
>
>> Bill Allen <wallenpb at gmail.com> writes:
>>
>>> If I have a list defined as my_list = ['a','b','c'], what is the is
>>> differnce between refering to it as my_list or my_list[:]?
>>
>> ?my_list? is a reference to the object you've already described (the
>> existing object ?['a', 'b', 'c']?).
>>
>> ?my_list[:]? is an operation that takes the original object and
>> creates a new one by slicing. In this case, the new object happens to
>> be equal to (but probably not identical to) the original, because of
>> the slice you specified.
>
> To demonstrate how identity differs from equality, use the appropriate
> comparison operators::
>
>      $ python3
>
>      >>> foo = ['a', 'b', 'c']
>
>      >>> bar = foo     # Bind the name ?bar? to the same object.
>      >>> bar           # Show me the object referred to by ?bar?.
>      ['a', 'b', 'c']
>      >>> bar == foo    # Is the object ?bar? equal to the object ?foo??
>      True
>      >>> bar is foo    # Is ?bar? referring to the same object as ?foo??
>      True
>
>      >>> baz = foo[:]  # Slice ?foo?, creating a new list; bind ?baz? to that.
>      >>> baz           # Show me the object referred to by ?baz?.
>      ['a', 'b', 'c']
>      >>> baz == foo    # Is the object ?baz? equal to the object ?foo??
>      True
>      >>> baz is foo    # Is ?baz? referring to the same object as ?foo??
>      False
>
> References which compare identical *are the same* object, guaranteed.
> Object identity almost always implies equality.
>
> (?almost always? because some object types have unusual behaviour like
> ?the object is not equal to itself?. Don't fret about that though, these
> exceptions are clearly defined when you find them.)
>
>
> References which compare equal *may under some conditions* be identical.
> This is *not* ever a promise, though, and you should never rely on it,
> not even in the same session of a program.
>
> Some of Python's internal optimisations depend on the fact that object
> equality *does not* imply object identity. If you happen to notice some
> operations producing the same object at one point in time, but the
> documentation doesn't promise it, then treat that as an unpredictable
> implementation detail and don't rely on it in your code.
>

Great description, if the OP really wants that level of detail.  But I 
think what he needs to know first is:

If you change foo, like       (untested)
     foo[1] = "new"

then you'll see that bar also changes (since it's just another name for 
the exact same object).
 >>> bar
['a', 'new', 'c']

But baz does not, since it's bound to a copy of the object.
 >>> baz
['a', 'b', 'c'\
-- 
DaveA

From alan.gauld at btinternet.com  Sat Apr 18 08:43:03 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 18 Apr 2015 07:43:03 +0100
Subject: [Tutor] lists, name semantics
In-Reply-To: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
Message-ID: <mgsudl$rme$1@ger.gmane.org>

On 18/04/15 04:16, Bill Allen wrote:
> If I have a list defined as my_list = ['a','b','c'], what is the is
> differnce between refering to it as my_list or my_list[:]?   These seem
> equivalent to me.  Is that the case?  Is there any nuance I am missing
> here?   Situations where one form should be used as opposed to the other?

Others have already given some good explanations.
I'll add a slightly different take.

Your confusion starts with your first statement:

 > I have a list defined as my_list = ['a','b','c']

What you should be saying is

I have a list defined as ['a', 'b', 'c']

Thats the list object that you are working with. The object is 
completely separate from the name that you choose to associate
with it.

You then bound that list to a name: my_list.
You could bind it to any number of names but
there would still only be one object:

foo = my_list
bar = foo
baz = my_list

Now I have 4 names all referring to the same list object.

The next source of confusion comes from another mist-statement:

 > differnce between refering to it as my_list or my_list[:]

The [:] at the end is an operator that returns a copy of the list.
So when you use it you are NOT referring to the original list
at all. You are creating a new copy.

So if we now take one of our previous names, say foo, and do:

foo = my_list[:]

foo no longer refers to your original list ['a','b','c']
but to a completely new copy of that list.

If you modify my_list the changes will show up when you look
at bar and baz as well. But foo will be unchanged

my_list[0] = 'z'
print baz   -> prints ['z','b','c'] - the same list as my_list
print foo   -> prints ['a','b','c'] - a different list object

Understanding the separation of names from objects in Python is 
essential to understanding how it works. It is different to many
other languages in this respect.

And understanding the difference between identity and value is also 
important. Two completely different objects can have the same value
and so appear the same but they are in fact entirely different.
Think about two drivers who both buy the exact same model of car.
They may look identical, but they are two separate cars.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From lac at openend.se  Sat Apr 18 02:04:11 2015
From: lac at openend.se (Laura Creighton)
Date: Sat, 18 Apr 2015 02:04:11 +0200
Subject: [Tutor] How to print ALL contents of a scrolled Tkinter window?
In-Reply-To: Message from Alan Gauld <alan.gauld@btinternet.com>
 of "Fri, 17 Apr 2015 21:06:35 +0100." <mgrp4a$suq$1@ger.gmane.org>
References: <CANDiX9+qVEJ6Ph8V8VSTGnC6wu1F6ME4t1GqvwnoO4dEcKqmNA@mail.gmail.com>
 <201504171429.t3HETlaG010853@fido.openend.se><mgrp4a$suq$1@ger.gmane.org>
Message-ID: <201504180004.t3I04BXk031485@fido.openend.se>

In a message of Fri, 17 Apr 2015 21:06:35 +0100, Alan Gauld writes:
>On 17/04/15 15:29, Laura Creighton wrote:
>
>> just use kivy, which has the advantage that is runs under IOS and
>> Android out of the box.
>
>But does Kivy support hard copy printing?
>That's pretty unusual behaviour on
>tablets/phones.

Every kivy app lives in precisely one window.  This window has a screenshot
method.  You can bind it to a button, and you will get a png of exactly
what your app looks like. 

Also, every widget has an export_to_png method which you can use to
capture the widget and its children.

So inside your program you can say -- start at the top of this widget,
display the first page, take screenshot, then scroll it one page, take
screenshot, repeat until done.  Which is a whole lot easier than fidding
with your app and taking screenshots from the outside.

Once you have the filename(s) you can print it/them however you normally print
files.  My printer lives on a wireless conection and my laptop, my desktop
and my tablet know how to talk to it.  (My phone does not, but it's over
5 years old now, and the android it runs is very old.  I'd upgrade it
in a second if some manufacturer would go back to making a 3.5 inch screen.
A phone that I cannot dial phone numbers on, one handed,  is of no use to
me. Grumble grumble.)

>> The whole point of kivy is to create better, new paradigm user interfaces,
>> where scrolling surfaces are built-in.
>
>That wouldn't be on mobile devices then,
>where the UIs are universally horrible IMHO! :-)
>They are the very antithesis of good user
>interface design.

You might enjoy playing with kivy, then, where the philosophy is 'we
can do much better than what we have now'.  Thinking about touch devices
and how to best use them (rather than how to emulate a mouse) is fun.

>Alan G
>Author of the Learn to Program web site
>http://www.alan-g.me.uk/
>http://www.amazon.com/author/alan_gauld

Laura Creighton



From wallenpb at gmail.com  Sat Apr 18 13:55:46 2015
From: wallenpb at gmail.com (Bill Allen)
Date: Sat, 18 Apr 2015 06:55:46 -0500
Subject: [Tutor] lists, name semantics
In-Reply-To: <mgsudl$rme$1@ger.gmane.org>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
Message-ID: <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>

Everyone that responded,

Thanks very much for the excellent explanations!  The distinction between a
reference to an object and a seperate copy of the object is quite clear now.

--Bill
On Apr 18, 2015 1:44 AM, "Alan Gauld" <alan.gauld at btinternet.com> wrote:

> On 18/04/15 04:16, Bill Allen wrote:
>
>> If I have a list defined as my_list = ['a','b','c'], what is the is
>> differnce between refering to it as my_list or my_list[:]?   These seem
>> equivalent to me.  Is that the case?  Is there any nuance I am missing
>> here?   Situations where one form should be used as opposed to the other?
>>
>
> Others have already given some good explanations.
> I'll add a slightly different take.
>
> Your confusion starts with your first statement:
>
> > I have a list defined as my_list = ['a','b','c']
>
> What you should be saying is
>
> I have a list defined as ['a', 'b', 'c']
>
> Thats the list object that you are working with. The object is completely
> separate from the name that you choose to associate
> with it.
>
> You then bound that list to a name: my_list.
> You could bind it to any number of names but
> there would still only be one object:
>
> foo = my_list
> bar = foo
> baz = my_list
>
> Now I have 4 names all referring to the same list object.
>
> The next source of confusion comes from another mist-statement:
>
> > differnce between refering to it as my_list or my_list[:]
>
> The [:] at the end is an operator that returns a copy of the list.
> So when you use it you are NOT referring to the original list
> at all. You are creating a new copy.
>
> So if we now take one of our previous names, say foo, and do:
>
> foo = my_list[:]
>
> foo no longer refers to your original list ['a','b','c']
> but to a completely new copy of that list.
>
> If you modify my_list the changes will show up when you look
> at bar and baz as well. But foo will be unchanged
>
> my_list[0] = 'z'
> print baz   -> prints ['z','b','c'] - the same list as my_list
> print foo   -> prints ['a','b','c'] - a different list object
>
> Understanding the separation of names from objects in Python is essential
> to understanding how it works. It is different to many
> other languages in this respect.
>
> And understanding the difference between identity and value is also
> important. Two completely different objects can have the same value
> and so appear the same but they are in fact entirely different.
> Think about two drivers who both buy the exact same model of car.
> They may look identical, but they are two separate cars.
>
> HTH
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From __peter__ at web.de  Sat Apr 18 14:49:19 2015
From: __peter__ at web.de (Peter Otten)
Date: Sat, 18 Apr 2015 14:49:19 +0200
Subject: [Tutor] lists, name semantics
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
Message-ID: <mgtjsg$h9j$1@ger.gmane.org>

Bill Allen wrote:

> Everyone that responded,
> 
> Thanks very much for the excellent explanations!  The distinction between
> a reference to an object and a seperate copy of the object is quite clear
> now.

You can test your newfound knowledge by predicting the output of the 
following script:


a = [1, ["x", "y"], 3]
b = a[:]

a[1][1] = "hello!"

print(a) # [1, ['x', 'hello!'], 3]
print(b) # what will that print?

Think twice before you answer. What is copied, what is referenced?


From joel.goldstick at gmail.com  Sat Apr 18 16:30:38 2015
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Sat, 18 Apr 2015 10:30:38 -0400
Subject: [Tutor] =Linked List Using Map
In-Reply-To: <mgrnt0$9jl$1@ger.gmane.org>
References: <55314ca1.c7628c0a.6f1c.ffffd77a@mx.google.com>
 <55314cc2.9512370a.1868.ffffd2c5@mx.google.com>
 <mgrnt0$9jl$1@ger.gmane.org>
Message-ID: <CAPM-O+xHOwLp8q5Y5r7AP=EQnYKswZHA8VHTCG78DqnvPk1jZw@mail.gmail.com>

>
> <rant>
> I hate when teachers ask students to do stupid stuff like this.
> It encourages so many bad practices it's positively dangerous!
> If they must have them reinvent the wheel at least let them
> use the native Python list to do it!
> </rant>
>
I suspect that the instructor is using Python as a second language,
and is picking examples from that language.  The use of non-standard
names strengthen's my opinion
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Joel Goldstick
http://joelgoldstick.com

From robertvstepp at gmail.com  Sat Apr 18 19:03:08 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 18 Apr 2015 12:03:08 -0500
Subject: [Tutor] How to print ALL contents of a scrolled Tkinter window?
In-Reply-To: <201504180004.t3I04BXk031485@fido.openend.se>
References: <CANDiX9+qVEJ6Ph8V8VSTGnC6wu1F6ME4t1GqvwnoO4dEcKqmNA@mail.gmail.com>
 <201504171429.t3HETlaG010853@fido.openend.se>
 <alan.gauld@btinternet.com> <mgrp4a$suq$1@ger.gmane.org>
 <201504180004.t3I04BXk031485@fido.openend.se>
Message-ID: <CANDiX9Kh99v-zNcDeQKqnr0B4ZLtvVwF6dbw3mZFtXmVpF14Pw@mail.gmail.com>

On Fri, Apr 17, 2015 at 7:04 PM, Laura Creighton <lac at openend.se> wrote:
> In a message of Fri, 17 Apr 2015 21:06:35 +0100, Alan Gauld writes:
>>On 17/04/15 15:29, Laura Creighton wrote:
>>
>>> just use kivy, which has the advantage that is runs under IOS and
>>> Android out of the box.
>>
>>But does Kivy support hard copy printing?
>>That's pretty unusual behaviour on
>>tablets/phones.
>
> Every kivy app lives in precisely one window.  This window has a screenshot
> method.  You can bind it to a button, and you will get a png of exactly
> what your app looks like.
>
> Also, every widget has an export_to_png method which you can use to
> capture the widget and its children.

Have these types of methods ever been considered for tkinter? They
would go a long way to giving people a way to print, while not getting
into a lot of OS hassle. In my particular scenario I would desire the
ability to output both postscript and pdf, though if I have the first
it is easy to get the latter.

boB Stepp

From robertvstepp at gmail.com  Sat Apr 18 19:15:07 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 18 Apr 2015 12:15:07 -0500
Subject: [Tutor] Star imports,
 was Re: How to get a Tkinter window to print a color copy of itself
 as a .pdf file?
In-Reply-To: <mgnpqt$bv$1@ger.gmane.org>
References: <CANDiX9L3gsgq-e=_MZF0ULO8DJXEY5LL0mRNyxyRbeFCiEie5w@mail.gmail.com>
 <mgm0oa$i28$1@ger.gmane.org>
 <CANDiX9K=BzV1SG3ZM4GyE_CbRDanThPcy8p-y88eLPtW5M-d+w@mail.gmail.com>
 <mgnpqt$bv$1@ger.gmane.org>
Message-ID: <CANDiX9LuygsjynqGqrp327Ruhxh5+4mMmvg-JU9MhJmfR_LOxQ@mail.gmail.com>

On Thu, Apr 16, 2015 at 2:54 AM, Peter Otten <__peter__ at web.de> wrote:
> boB Stepp wrote:
>
>>> import Tkinter as tk
>>
>> Question: I have been using "from Tkinter import *" as suggested in
>> "Programming Python" by Lutz. He remarks that unlike other situations,
>> this is generally safe with Tkinter. Is there a benefit to doing the
>> import as you have?
>
> It's a stylistic preference: I like to keep namespaces separate.

After reading your full post, you have convinced *me* this is more
than stylistic preference.

> When I make an exception, typically for generic functionality like
>
> contextmanager, groupby, namedtuple, defaultdict...
>
> I import these in a controlled way with
>
> from collections import defaultdict
> from itertools import islice, zip_longest

Making it very clear to anyone who comes later.

> etc., use them as "pseudo-builtins", and avoid writing functions with the
> same name myself. By contrast I have no clear idea of what's in the tkinter
> package and might write my own getint() function, say, thus forcing a reader
> to scan the complete module to learn which getint() is used.

This in particular applies to me at my current stage of learning as I
have only scattered knowledge of all that is in the tkinter package.

> This is a general problem of star imports; when you overwrite an imported
> name you typically don't care or even know about that name in the imported
> module. When you read your module later to fix or amend something your
> knowledge may have grown, and you expect the imported function where the
> custom function is used. This confusion becomes even more likely when a
> second developer is involved.

You are so persuasive here that forthwith I will change to a
substantially explicit format of importing!

-- 
boB

From robertvstepp at gmail.com  Sat Apr 18 21:01:19 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 18 Apr 2015 14:01:19 -0500
Subject: [Tutor] How (not!) lengthy should functions be?
In-Reply-To: <mgovt3$ipn$1@ger.gmane.org>
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
 <mgovt3$ipn$1@ger.gmane.org>
Message-ID: <CANDiX9KvfEaeMqKWgB_r_CazQGAsrqruXYWx_TcRH4DQ60w-rA@mail.gmail.com>

On Thu, Apr 16, 2015 at 1:43 PM, Peter Otten <__peter__ at web.de> wrote:

> However, there's more to it. You are working in an environment where people
> may be harmed if you get your numbers wrong, and nothing hinders you to swap
> the arguments in your percent2Gy() function or even pass it a length and an
> amount of dollars. You need measures to make this unlikely.

I am attempting to do this. In a large sense, the whole purpose of my
program is to evaluate what the planner has already done. The planner
at this point would normally believe he has a deliverable plan that
satisfies everything his physician requires. At this point he would
normally have the physician review his plan and approve it. The
planner has this degree of certainty at this point. The point of this
program is to provide additional checking to ensure nothing has been
overlooked by the planner before he presents the plan to the
physician. The program changes nothing in his plan. It is just a
reader of existing plan data and then evaluates it against a variety
of criteria. The planner *should* have already done this process
himself. The program merely double-checks everything (And adds
additional checking that I believe should be done, but not necessarily
all of my colleagues agree with me on this.).

> Unambiguous function names and keyword-only parameters (not available in
> Python 2) and of course tests help, but you might also consider custom types
> that are restricted to a well-defined set of operations. A sketch:

I do check the numbers and units both for falling within a proper
range of allowed values and correct associated units for what is being
measured. This happens at several places, but not every place where
the information is is used. But data is checked as it enters the
workflow and at multiple points during the program's workflow and
finally at the end result. Since I am not writing classes yet I am not
taking this approach yet. But I see a greater value in doing it this
way as the information would be constantly checked for validity.

> # For illustration purpose only!
> class Percent:
>     def __init__(self, value):
>         if value < 1 or value > 100: # XXX allow 0%?
>             raise ValueError
>         self.value = value
>     def factor(self):
>         return self.value / 100.0
>     def __repr__(self):
>         return "{} %".format(self.value)

Something like this would have to be tweaked depending on what
structure and what parameter is being evaluated. Actual dose to
*something* in the patient can vary between 0% (For something
receiving essentially no dose--far from the area of treatment.) to the
value of point of maximum dose, which, for an SBRT-type plan, could be
as high as 160% of prescription dose. Of course such high doses are
only allowed to occur within the confines of the tumor being treated
(NEVER outside of it!).

[...]

>     target_dose.partial_dose(0.1) # raises TypeError
>
> Output:
>
> $ python gray.py
> 20 Gy
> 2.0 Gy
> 2.0 Gy # 10 % of the target dose
> Traceback (most recent call last):
>   File "gray.py", line 43, in <module>
>     target_dose.partial_dose(0.1) # raises TypeError
>   File "gray.py", line 27, in partial_dose
>     raise TypeError
> TypeError

I generate an output very similar to this except I must get the error
to show up in the planning system software. I rephrase the error
message into language that the planner will understand that makes
sense in the context of his plan. If it is an issue with his plan, he
will know exactly what the issue is and how to address it.

For errors that indicate an issue with my coding the planner would
receive a message that states where within the program the error
occurred, using language that will make sense to the planner, but also
pinpoint exactly where the error was generated. And to contact me
immediately with the issue.

> OK, I got carried away a bit with my example, but you might get an idea
> where I'm aiming at. The way I wrote it it is pretty clear that Percent(10)
> denote 10 rather than 1000 %.

Amen!

> I can't spare you a last remark: Python may not be the right language to
> make this bulletproof.

Would you elaborate on this? I am sure I don't have the experience
with programming and programming languages to truly understand your
point.

As I final note I want to emphasize that I am not writing a program to
*create* a treatment plan. Nor am I writing a program that can *alter*
an existing treatment plan. It is merely reading output from the
treatment plan and evaluating that output against agreed upon best
practice numbers. If this program never gets implemented it will
change nothing in how plans are created and implemented. If it does
get implemented, then the planner will do what he would have done
anyway in the absence of the program. However, if the program flags
something for his attention, then something will get  noticed that
might not have. I wish to emphasize that most of these *somethings*
would not be actual errors that would cause any harm to a patient;
instead, it would suggest ways the planner can make his viable
treatment plan even better: Improve target coverage even more; notice
that organ x's sparing could be improved without decreasing target
coverage; etc. Even though I am attempting to make this program as
*bulletproof* as my knowledge and experience allows, it cannot affect
anyone's treatment. It is purely a supplemental level of checking,
much like the many, ... , many human checks that we already implement.
And this feedback, whether human or program-based, is to make a good
plan even better, which will result in even better patient outcomes.

boB

From robertvstepp at gmail.com  Sat Apr 18 21:30:12 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 18 Apr 2015 14:30:12 -0500
Subject: [Tutor] How (not!) lengthy should functions be?
In-Reply-To: <mgp83i$vpk$1@ger.gmane.org>
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
 <mgp83i$vpk$1@ger.gmane.org>
Message-ID: <CANDiX9J069vV=T7H2yreX8WZ=JW9xoqFkZ=Z4bOgQg92v78XKA@mail.gmail.com>

On Thu, Apr 16, 2015 at 4:03 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 16/04/15 17:47, boB Stepp wrote:

[...]

> 2) I have seen varying recommendations as to number of lines of code
>
> Most of these come from the days when we worked on dumb terminals with 24
> line screens. Actual measurements has shown that function length (within
> reason!) is not a major factor in comprehension or reliability. In COBOL or
> C it is not unreasonable to have functions over 50 lines long, sometimes
> over a hundred. But in Python that would be very unusual. So I'd treat the
> advise to limit length to about 20 lines of executable code to still be
> valid, if you exceed it treat it as a red flag to check that you really need
> it to be that long.

Would not your comments above apply to line length as well? If yes,
why are we still wedded to a 79-80 character limit to lines when most
people's monitors are quite expansive, to put it mildly?

boB

From alan.gauld at btinternet.com  Sat Apr 18 22:05:51 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 18 Apr 2015 21:05:51 +0100
Subject: [Tutor] How (not!) lengthy should functions be?
In-Reply-To: <CANDiX9J069vV=T7H2yreX8WZ=JW9xoqFkZ=Z4bOgQg92v78XKA@mail.gmail.com>
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
 <mgp83i$vpk$1@ger.gmane.org>
 <CANDiX9J069vV=T7H2yreX8WZ=JW9xoqFkZ=Z4bOgQg92v78XKA@mail.gmail.com>
Message-ID: <mgudet$ef7$1@ger.gmane.org>

On 18/04/15 20:30, boB Stepp wrote:

>> line screens. Actual measurements has shown that function length (within
>> reason!) is not a major factor in comprehension or reliability.
>
> Would not your comments above apply to line length as well?

Actually no.
Research has shown that people's comprehension hits a limit with
lines around 12-15 words long. That's about 70 characters. So 
translating that (text based) metric to code means the 80
character limit is still quite sane.

Although I have written code with a limit of 130 chars (on an old VT330 
that had a "wide" setting and could print out on a 30inch line printer)...

But there is a reason most books are portrait format and use the
font sizes they do. (and why newspapers use columns). It's the
limits of human comprehensibility. A topic that has been studied
in some depth, not just in CompSci but also in graphics
design, linguistics and journalism.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Sat Apr 18 22:13:10 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 18 Apr 2015 21:13:10 +0100
Subject: [Tutor] How to print ALL contents of a scrolled Tkinter window?
In-Reply-To: <CANDiX9Kh99v-zNcDeQKqnr0B4ZLtvVwF6dbw3mZFtXmVpF14Pw@mail.gmail.com>
References: <CANDiX9+qVEJ6Ph8V8VSTGnC6wu1F6ME4t1GqvwnoO4dEcKqmNA@mail.gmail.com>
 <201504171429.t3HETlaG010853@fido.openend.se> <alan.gauld@btinternet.com>
 <mgrp4a$suq$1@ger.gmane.org> <201504180004.t3I04BXk031485@fido.openend.se>
 <CANDiX9Kh99v-zNcDeQKqnr0B4ZLtvVwF6dbw3mZFtXmVpF14Pw@mail.gmail.com>
Message-ID: <mgudsk$ef7$2@ger.gmane.org>

On 18/04/15 18:03, boB Stepp wrote:

> Have these types of methods ever been considered for tkinter?

I don't follow the TK and Tkinter mailing lists closely.
You are probably better asking there.

There is a gmane news feed for a Tkinter mailing list
as well as an archive

gmane.comp.python.tkinter

And the general Tk fora at:

www.tcl.tk

They may even have a solution, in which case let us know.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From robertvstepp at gmail.com  Sat Apr 18 22:17:42 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 18 Apr 2015 15:17:42 -0500
Subject: [Tutor] How to print ALL contents of a scrolled Tkinter window?
In-Reply-To: <mgrmsj$ohl$1@ger.gmane.org>
References: <CANDiX9+qVEJ6Ph8V8VSTGnC6wu1F6ME4t1GqvwnoO4dEcKqmNA@mail.gmail.com>
 <mgrmsj$ohl$1@ger.gmane.org>
Message-ID: <CANDiX9+KpudyXDPFPt0C+fuZAAih701+xW83XCH0E=pcZFU_CA@mail.gmail.com>

On Fri, Apr 17, 2015 at 2:28 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 17/04/15 14:26, boB Stepp wrote:
>>
>> Solaris 10, Python 2.4.4
>>

[...]

> That's why GUI printing generally uses an entirely different
> technique to print things (see my earlier email). In essence
> this requires you to separate the data content and format
> from the GUI presentation. The printed presentation must be
> prepared by you the programmer and output to the new display
> context(a printer). This means you need to decide how to
> handle page breaks, page width and orientation etc etc.

I had started thinking along these lines, but realized that I possess
a severe lack of knowledge as to the details of the printer does its
*magic*. I used to know a bit about how dot-matrix printers
(non-color) worked, but that has been a very long time ago...

You mentioned groff in the other thread. Is this relatively easy to
adapt to its formatting commands? Is it likely to be on my bare-bones
Solaris 10 workstation? I will have to check to see what is present
Monday.

> Its a whole different ballgame and much more complex than
> simply issuing a print command. Hard copy output from a
> GUI is one of the hardest things to do in almost any GUI,
> especially if you want it truly WYSIWYG.

I am surprised that Python does not have a standard library module to
help with this. I see that there are third-party modules, but that
does not help me within my work environment constraints.

> My personal favourite approach is to abandon WYSIWYG and
> go for WYSRWYG - What you see resembles what you'll get...
> And then I reformat the data using HTML, send it to a file
> and print that file using whatever HTML rendering engine
> I can find.

Are there such HTML rendering engines likely to be present in a
Solaris 10 environment, which is a rather bare-bones environment? I
mean outside of a web browser. I can already use my existing template
to auto-generate the appropriate HTML formatting (Once I write the
needed functions to do so. But it should logically no different than
how I interpret my template to render the Tkinter GUI display.), save
that in a file and then? This would be needed to be done
programmatically, not manually by the user. The desired end result is
a pdf document to be stored electronically for posterity.

> wxPython makes printing easier but even there its a
> whole chapter(ch17) of the book and its at the end so
> assumes you already know all the background around sizers,
> device context and the like.... The example program - for
> printing a formatted text document - runs to 2.5 pages of
> code. And that's the easiest printing framework I've seen.

Which book are you referencing here? Would it be "Wxpython in Action"?

>> are along the lines of: 1) Determine how many rows of information
>> appear in the viewing area. 2) Determine how many total rows of
>> information exist to be printed. 3) Figure out how to programmatically
>> do a *manual* scroll to bring up the hidden scrolled information. 4)
>> Repeatedly apply the printing method. While I can probably make this
>> approach work (It *seems* conceptually simple.), I cannot help but
>> feel there is a much better way...
>
>
> Its never going to be pretty but multiple screen captures
> can work. Its certainly easy enough to reposition a scroll
> bar programmatically from within a while loop. Figuring out
> how many lines will depend on all sorts of things like
> the size of fonts being used, how widgets are laid out.
> That's what gets tricky, especially if users don't have
> standardised screen sizes etc.

I may or may not go this way. I already wrote a set of scripts (in
shell and Perl) a few years ago to allow the user to click and drag an
area of their screen to capture into a pdf document. It leverages the
existing printer configurations and tools in the planning software.
When the user is finishing making captures, he clicks the "Print to
pdf" button and it converts the captures into a single pdf document,
which it then ftps to the desired destination folder on a different
portion of our intranet. This would provide a workable solution until
I learn more.

>> I intend to scour my available Tkinter documentation to see if there
>> are root window level and scrolled area commands that might suggest
>> another approach.
>
>
> Not really. Tkinter (and Tk) basically sidesteps printing
> to hard copy. There simply is no built in support. You have
> to format it yourself.

I did not find even a hint of anything beyond the already known Canvas
widget postscript capability.

> Check out IDLE - even it doesn't have any built in
> formatted print. It only has 'Print Window', which is
> just plain text.
> Although even looking at how they did that might
> help too. Remember you have the code to IDLE and
> its built using Tkinter...

I will make time to do this. Hopefully it will provide better modes of
thinking on my part!

Thanks, Alan!

boB

From wallenpb at gmail.com  Sat Apr 18 22:28:58 2015
From: wallenpb at gmail.com (Bill Allen)
Date: Sat, 18 Apr 2015 15:28:58 -0500
Subject: [Tutor] lists, name semantics
In-Reply-To: <mgtjsg$h9j$1@ger.gmane.org>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
Message-ID: <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>

print(b) will print the original copy of a which b now references which is
[1, ["x", "y"], 3]
On Apr 18, 2015 7:50 AM, "Peter Otten" <__peter__ at web.de> wrote:

> Bill Allen wrote:
>
> > Everyone that responded,
> >
> > Thanks very much for the excellent explanations!  The distinction between
> > a reference to an object and a seperate copy of the object is quite clear
> > now.
>
> You can test your newfound knowledge by predicting the output of the
> following script:
>
>
> a = [1, ["x", "y"], 3]
> b = a[:]
>
> a[1][1] = "hello!"
>
> print(a) # [1, ['x', 'hello!'], 3]
> print(b) # what will that print?
>
> Think twice before you answer. What is copied, what is referenced?
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From robertvstepp at gmail.com  Sat Apr 18 23:10:32 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 18 Apr 2015 16:10:32 -0500
Subject: [Tutor] lists, name semantics
In-Reply-To: <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
Message-ID: <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>

On Sat, Apr 18, 2015 at 3:28 PM, Bill Allen <wallenpb at gmail.com> wrote:
> On Apr 18, 2015 7:50 AM, "Peter Otten" <__peter__ at web.de> wrote:
>
>> Bill Allen wrote:
>>
>> > Everyone that responded,
>> >
>> > Thanks very much for the excellent explanations!  The distinction between
>> > a reference to an object and a seperate copy of the object is quite clear
>> > now.
>>
>> You can test your newfound knowledge by predicting the output of the
>> following script:
>>
>>
>> a = [1, ["x", "y"], 3]
>> b = a[:]
>>
>> a[1][1] = "hello!"
>>
>> print(a) # [1, ['x', 'hello!'], 3]
>> print(b) # what will that print?
>>
>> Think twice before you answer. What is copied, what is referenced?

> print(b) will print the original copy of a which b now references which is
> [1, ["x", "y"], 3]

Uh, oh! You should have checked your work in the interpreter before
replying! Peter is being very tricky!! (At least for me...) Look again
at that list inside of a list and...

boB

P.S.: Watch out for top-posting. That tends to get peopled riled. I
moved your response back into the normal flow of the interleaved
conversation.

From davea at davea.name  Sun Apr 19 00:46:37 2015
From: davea at davea.name (Dave Angel)
Date: Sat, 18 Apr 2015 18:46:37 -0400
Subject: [Tutor] How (not!) lengthy should functions be?
In-Reply-To: <CANDiX9KvfEaeMqKWgB_r_CazQGAsrqruXYWx_TcRH4DQ60w-rA@mail.gmail.com>
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
 <mgovt3$ipn$1@ger.gmane.org>
 <CANDiX9KvfEaeMqKWgB_r_CazQGAsrqruXYWx_TcRH4DQ60w-rA@mail.gmail.com>
Message-ID: <5532DECD.3040800@davea.name>

On 04/18/2015 03:01 PM, boB Stepp wrote:
>
> As I final note I want to emphasize that I am not writing a program to
> *create* a treatment plan. Nor am I writing a program that can *alter*
> an existing treatment plan. It is merely reading output from the
> treatment plan and evaluating that output against agreed upon best
> practice numbers. If this program never gets implemented it will
> change nothing in how plans are created and implemented. If it does


I'd still point out that eventually people will presumably get to 
believing in your program.  They'll subconsciously assume that if they 
mess up, the program will notice, so they don't have to be as careful as 
they otherwise would.

There's nothing you can do about this; it's human nature.  So I claim 
that making sure the advice your program offers has
   1) few bugs.  And what it has should be crashes, not just getting the 
wrong result.
   2) Careful wording of the messages to indicate the confidence level 
of the conclusion it's relating.


-- 
DaveA

From steve at pearwood.info  Sun Apr 19 05:02:33 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 19 Apr 2015 13:02:33 +1000
Subject: [Tutor] =Linked List Using Map
In-Reply-To: <55314cc2.9512370a.1868.ffffd2c5@mx.google.com>
References: <55314ca1.c7628c0a.6f1c.ffffd77a@mx.google.com>
 <55314cc2.9512370a.1868.ffffd2c5@mx.google.com>
Message-ID: <20150419030232.GA5663@ando.pearwood.info>

Hello Ni'Yana, and welcome!

On Fri, Apr 17, 2015 at 06:11:00PM +0000, niyanaxx95 at gmail.com wrote:

> Hello I need guidance trying to solve my assignment. I am completely 
> lost when using maps with linked lists. I understand linked lists 
> though. May someone work with me?

We will not do your homework, but perhaps we can guide you.

Thank you for showing your code. It looks like you have already made a 
lot of progress.

Unfortunately, the one thing you did not tell us is what part of the 
assignment you are having problems with! It looks like you have done 
most of the work correctly so far, so what part is giving you trouble?

A few comments on your code below:


> class Node:
>     def __init__( self, item, next = None ) :
>         self.item = item
>         self.next = next
>     def getItem( self ) :
>         return self.item
>     def getNext( self ) :
>         return self.next
>     def setItem( self, item ) :
>         self.item = item
>     def setNext( self, next ) :
>         self.next = next

Your Node class looks straightforward, but it doesn't match the 
requirements. The requirement for the Map is that it must have key:value 
pairs. But your Node doesn't have two data fields, it only has one! So 
you cannot give the Node both a key and a value.

Your Node class needs to start like this:

class Node:
    def __init__(self, key, value, next=None):
        self.key = key
        self.value = value
        self.next = next


That will help get the Map class right. See my comments below.


> class Map:
>     def __init__( self, contents = []) :
>         self.first = LinkedList.Node(None, None)

First problem: you have added code which is not part of the 
specifications. The assignment says that calling Map() returns a new 
empty map. It says nothing about Map([1, 2, 3]). Get rid of the 
"contents" argument, it is not required. Once you get rid of that, the 
"for e in contents" loop is not required. Get rid of it!

Second problem: LinkedList is not defined anywhere. What is it?

The easiest way for this to work is to put the None class and the Map 
class in the same file, and then you can just say:

        self.first = Node(None, None)

without worrying about the name of the file. Java has a rule that each 
class, no matter how tiny, must go in its own file, but Python does not
have such a rule. Related classes may go in the same file.

Third problem: your assignment to self.first is wrong! That gives 
the Map a single item, not zero items!

An empty linked list will be represented here by just None alone.

        self.first = None

You then traverse the linked list like this:


    node = self.first
    while node is not None:
        print("key = %s, value = %s" % (node.key, node.value))
        node = node.next

which will print all the keys and values in the map.

To add a new node to the end, you do this:

    node = self.first
    # The empty Map case is special.
    if node is None:
        self.first = Node("the key", "some value")
    else:
        while node.next is not None:
            node = node.next
        # Now we are at the end of the linked list.
        # Add a new node.
        node.next = Node("the key", "some value")

>         self.last = self.first
>         self.numItems = 0
>         for e in contents:
>             self.append(e)
>             
>     def __len__( self ) :
>         count = 0
>         while self != None:
>             count +=1
>             self = self.next
>         return count

I don't think that this will do what your assignment asks. 

The first problem is that your assignment says that your Map must have a 
method called `length` which returns the number of items. Your Map class 
has no method called `length`, instead it uses the Python special 
__len__ method.

I think you need to change the name of this __len__ method to length. It 
is still be buggy (have you tested it?) but at least it will do what the 
assignment says.

Let us think about how to implement this length method. It is actually 
very easy! Your Map class already has a counter which tell you how many 
items are in the map, and it is initialised with:

        self.numItems = 0

so length is easy:

def length(self):
    return self.numItems


Now all you need to do is make sure that every time you add a node to 
the Map, add 1 to numItems, and every time you delete a node, you 
subtract 1.


>     def contains() :
>         pass

I assume this is just a stub which is not finished yet.

The contains method just needs to walk the linked list and look for the 
key. I showed you code above that walks the linked list printing keys 
and values. Instead of printing, you compare the node's key to the key 
you are looking for, and if they are equal, return True:

        while node is not None:
            if node.key == key:
                return True


If you reach the end of the linked list without finding the key, you 
have to return False.


Both your __setitem__ and __getitem__ methods also ignore what the 
assignment says. The assignment wants methods called `setitem` and 
`getitem`, not the special Python double-underscore methods. So you need 
to change their names, then test them.

Also, they fail to do what the assignment says. Read the requirements:

getitem(key): Returns the value associated with the given key, which 
must exist.

Does your __getitem__ method take a key as argument? No it does not, it 
takes an index!

getitem needs to take a single argument, the key. It then walks the 
linked list (as I showed you above), comparing the node's key to the 
wanted key. If they are equal, you then return node.value. If they are 
not equal, go on to the next node.

If you run out of nodes before finding the key, that is an error.

setitem needs to take two arguments, a key and a value. You then walk 
the linked list (again!) and compare the node's key to the wanted key. 
If they are equal, you set the node's value to the new value:

    node.value = value

and return.

If you run out of nodes, you add a new node at the end.

Remember what I said about incrementing the counter!

By this time, you should see a pattern. Nearly all these methods 
demonstrate the same sort of procedure: you walk the linked list, 
looking at each node in turn:

    node = self.first
    while node is not None:
        do_something_with(node)



-- 
Steve

From wallenpb at gmail.com  Sun Apr 19 05:03:56 2015
From: wallenpb at gmail.com (Bill Allen)
Date: Sat, 18 Apr 2015 22:03:56 -0500
Subject: [Tutor] lists, name semantics
In-Reply-To: <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
Message-ID: <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>

On Apr 18, 2015 4:11 PM, "boB Stepp" <robertvstepp at gmail.com> wrote:
>
> On Sat, Apr 18, 2015 at 3:28 PM, Bill Allen <wallenpb at gmail.com> wrote:
> > On Apr 18, 2015 7:50 AM, "Peter Otten" <__peter__ at web.de> wrote:
> >
> >> Bill Allen wrote:
> >>
> >> > Everyone that responded,
> >> >
> >> > Thanks very much for the excellent explanations!  The distinction
between
> >> > a reference to an object and a seperate copy of the object is quite
clear
> >> > now.
> >>
> >> You can test your newfound knowledge by predicting the output of the
> >> following script:
> >>
> >>
> >> a = [1, ["x", "y"], 3]
> >> b = a[:]
> >>
> >> a[1][1] = "hello!"
> >>
> >> print(a) # [1, ['x', 'hello!'], 3]
> >> print(b) # what will that print?
> >>
> >> Think twice before you answer. What is copied, what is referenced?
>
> > print(b) will print the original copy of a which b now references which
is
> > [1, ["x", "y"], 3]
>
> Uh, oh! You should have checked your work in the interpreter before
> replying! Peter is being very tricky!! (At least for me...) Look again
> at that list inside of a list and...
>
> boB
>
> P.S.: Watch out for top-posting. That tends to get peopled riled. I
> moved your response back into the normal flow of the interleaved

boB,

Ok, just tried it out.  In this example b=a and b=a[:] seem to yield the
same results even after the change to a, which I do not understand.  Should
not b be a copy of a and not reflect the change?

--bill

From robertvstepp at gmail.com  Sun Apr 19 05:28:39 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 18 Apr 2015 22:28:39 -0500
Subject: [Tutor] How (not!) lengthy should functions be?
In-Reply-To: <5532DECD.3040800@davea.name>
References: <CANDiX9KvFP88HiYa9Wr6Vx_LqoiWgdW9BUCF=On+gbvotR=69w@mail.gmail.com>
 <mgovt3$ipn$1@ger.gmane.org>
 <CANDiX9KvfEaeMqKWgB_r_CazQGAsrqruXYWx_TcRH4DQ60w-rA@mail.gmail.com>
 <5532DECD.3040800@davea.name>
Message-ID: <CANDiX9+thccj4hvu8vJ4SFfg_hvUz1RZnamdTAMLnbg=Tr-Fwg@mail.gmail.com>

On Sat, Apr 18, 2015 at 5:46 PM, Dave Angel <davea at davea.name> wrote:

> I'd still point out that eventually people will presumably get to believing
> in your program.  They'll subconsciously assume that if they mess up, the
> program will notice, so they don't have to be as careful as they otherwise
> would.

Well understood! I have observed this in other things I have done that
are being used, including the ancestor of this current project. I do
not believe I have spoken much of it. It had been in use for
approximately one year when I first discovered python and this mailing
list. It is similarly a plan evaluation program, except it is used for
the evaluation of our SBRT (stereotactic body radiation therapy)
plans, whereas this  project in development will be used -- at least
initially-- to evaluate *normal* treatment plans. I think it has been
in continuous use for going on four years now. It has never given an
incorrect result. It has never failed its monthly constancy checks. It
has rarely had a bug arise.  When it has happened, it has been for
something a user tried to do that I never imagined happening. But in
each such instance (Keep fingers crossed, etc.) it has either crashed
or displayed an error message describing the error, stopped program
execution, and to contact me. The problem with this program is at the
time of creating it, I knew its design was bad, but I did not have any
options at the time. I needed the ability to display a graphical
display of the plan analysis, but the only option our castrated work
stations provided was to use the planning system's ability to create
and display GUI elements. All of our workstations had Perl installed,
but were missing dependencies (Which I was not allowed to correct.) to
allow for GUI generation. I could have investigated the early versions
of Java installed, but I wasn't prepared to go that route then. I
tentatively looked into C/C++, but initial investigations revealed
missing libraries, etc. there as well. So in the end I developed this
hybrid of Perl code and planning system scripting language. You would
not like the structure of the scripting language! I could go on quite
a while, but I'll just mention that ALL variables are essentially both
global and persistent. The variables and what they store do not go
away until you exit the plan or purposefully destroy them. If I run
one script, finish it and run a totally unrelated script it will have
access to all variables and their last contents from the previous
script unless the programmer explicitly destroyed those variables
prior to that script's termination. Talk about potentially clashing
namespaces!

Because of these and other limitations that I had to work with, I was
forced to have some program logic and substantial portions of the
constraint data integrated with the GUI generation code. This led to
maintenance hell the one time the constraint data had changed almost a
couple of years ago. Steven's analogy of hammering nails with a paint
brush comes to mind! But I got it to work and to work well. And this
is much better than planners repeatedly doing by-hand calculations
over and over and ... and over while they are trying to develop a
viable plan. Which process is more likely to develop a patient
critical error? Especially as the planner becomes fatigued under
potentially heavy patient loads, where he must develop plans under
time pressures? So I provided a solution that works. The planner uses
it as a tool while developing his plans, undoubtedly *not* checking
*any* of the calculations he used to do by hand. SUBSTANTIAL amounts
of human labor are saved. When the planner feels he has a good plan,
THEN he checks all of the program's calculations. If this is
satisfactory, then he proceeds to getting the physician, etc.

I believe that I come across on this list as much more ignorant and
perhaps even much stupider than I actually am. This is because I am
the sort of person who is unafraid to ask questions, no matter how
trivial or how stupid I might make myself look by doing the asking.  I
would rather be absolutely certain that I understand what I am trying
to do and the implications of what I am trying to do, then not ask due
to potential embarrassment. At the very least, I want to identify the
boundaries of my ignorance and incompetence. And after further
pondering, if I feel I am still missing the boat on something, I'll
have a go at asking again until I am satisfied with my comprehension.
That is why I am so grateful to have access to your willing help and
expertise!

Anyway, back to the current project: The moment that they upgraded our
systems, so that not only did I have full access to Python, no matter
how old, but also that Tkinter was fully installed, was the moment I
started designing a complete rewrite of the above-mentioned program.
No matter how well working the program currently is, I *must* correct
its major design flaws now that I have the tools available to do so.
And I much prefer editing data files to editing programs into which
data is embedded!! And my intent is to make everything even safer by
interacting with the underlying planning software as minimally as
possible. I want this new program to be as close to a strict reader of
planning system output as I can make it and do ALL processing and
display of the data external to the planning system. Especially as
every time the planning system software is upgraded it seems to come
with a new set of its own bugs.

And if it comforts anyone, if anyone asked me to write software that
would directly control, interact with or potentially alter a patient's
*actual* treatment, I would refuse point blank--even if it cost me my
job-- because I know that my current knowledge and skill sets could
not safely accomplish such a project.

I do not know if I actually needed to say any of the above, but I feel
better for having said it! ~(:>))

> There's nothing you can do about this; it's human nature.  So I claim that
> making sure the advice your program offers has
>   1) few bugs.  And what it has should be crashes, not just getting the
> wrong result.
>   2) Careful wording of the messages to indicate the confidence level of the
> conclusion it's relating.

Trying to do my very, very best!


-- 
boB

From robertvstepp at gmail.com  Sun Apr 19 06:07:54 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 18 Apr 2015 23:07:54 -0500
Subject: [Tutor] lists, name semantics
In-Reply-To: <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
 <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
Message-ID: <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>

On Sat, Apr 18, 2015 at 10:03 PM, Bill Allen <wallenpb at gmail.com> wrote:
>
> On Apr 18, 2015 4:11 PM, "boB Stepp" <robertvstepp at gmail.com> wrote:
>>
>> On Sat, Apr 18, 2015 at 3:28 PM, Bill Allen <wallenpb at gmail.com> wrote:
>> > On Apr 18, 2015 7:50 AM, "Peter Otten" <__peter__ at web.de> wrote:
>> >
>> >> Bill Allen wrote:

[...]

>> >> You can test your newfound knowledge by predicting the output of the
>> >> following script:
>> >>
>> >>
>> >> a = [1, ["x", "y"], 3]
>> >> b = a[:]
>> >>
>> >> a[1][1] = "hello!"
>> >>
>> >> print(a) # [1, ['x', 'hello!'], 3]
>> >> print(b) # what will that print?
>> >>
>> >> Think twice before you answer. What is copied, what is referenced?
>>
>> > print(b) will print the original copy of a which b now references which
>> > is
>> > [1, ["x", "y"], 3]
>>
>> Uh, oh! You should have checked your work in the interpreter before
>> replying! Peter is being very tricky!! (At least for me...) Look again
>> at that list inside of a list and...

[...]

> Ok, just tried it out.  In this example b=a and b=a[:] seem to yield the
> same results even after the change to a, which I do not understand.  Should
> not b be a copy of a and not reflect the change?

Like you, I am on the path to learning Python, so I may or may not get
all the technical details correct, but here goes (I'm certain that if
I take any misstepps --pun intended!--that the ever-helpful crew of
professionals will set us both straight):

So far the emphasis on your original question has been on the
differences between 'references to objects' and the actual 'objects'.
I think that for the purpose of your question you can think about
'objects' as some sort of data stored someplace, though this is not
technically correct. When an item of data is stored, it is more
efficient to store it once and then from that point on use identifiers
(Which we are used to thinking of in most instances as 'variables'.)
to point to the storage location of that particular item of data. So
when you originally said something like:

my_list = ['a', 'b', 'c']

The ['a', 'b', 'c'] is the item of data stored and my_list is the
identifier identifying *where* this particular item of data is stored.
If you then do things like say:

some_other_identifier = my_list

then you just created a new identifier which gives the same location
information to exactly the same piece of data. However, fortunately
(Or, unfortunately, depending on your point of view.) you picked a
type of data -- a list -- that is *mutable*. Like mutations in
genetics, this just means that this item of data is capable of being
changed in place, i.e., where it is actually stored in memory. So if
Peter had said instead something like (Using the above statements.):

some_other_identifier[1] = 'Hello!'

I think you understand now that the originally *identified* list would
now be ['a', 'Hello!', 'c'] .

But Peter's actual example had a list inside of a list and BOTH of
these are objects (In our discussion, items of data.) and BOTH of
these have this property of being *mutable*. So he stuck an object
inside of another object, so to speak. And this inner object has
identifiers associated with it, too! Before Peter changed one of these
changeable objects, he had:

a = [1, ["x", "y"], 3]
b = a[:]

Now BOTH a[1] and b[1] now identify the location of the inner list
object, ["x", "y"] . Apparently, Python, in its ever efficient memory
management  fashion, when it creates the new object/piece of data
a[:], it sees no need to duplicate the inner list object, ["x", "y"],
but instead creates another identifier/pointer/reference to this
object's location. But since this inner list object is mutable, when
you change "y" to "hello!" in b, you also change it in a because both
a[1][1] and b[1][1] reference/point to the exact same storage location
where this element of the inner list is actually stored.

I hope this is helpful, and, if there are any misstepps, that when
they are revealed both of our understandings will be enhanced!

boB Stepp

From cs at zip.com.au  Sun Apr 19 06:08:06 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Sun, 19 Apr 2015 14:08:06 +1000
Subject: [Tutor] lists, name semantics
In-Reply-To: <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
References: <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
Message-ID: <20150419040806.GA80371@cskk.homeip.net>

On 18Apr2015 22:03, Bill Allen <wallenpb at gmail.com> wrote:
>On Apr 18, 2015 4:11 PM, "boB Stepp" <robertvstepp at gmail.com> wrote:
>> On Sat, Apr 18, 2015 at 3:28 PM, Bill Allen <wallenpb at gmail.com> wrote:
>> > On Apr 18, 2015 7:50 AM, "Peter Otten" <__peter__ at web.de> wrote:
>> >> You can test your newfound knowledge by predicting the output of the
>> >> following script:
>> >>
>> >> a = [1, ["x", "y"], 3]
>> >> b = a[:]
>> >>
>> >> a[1][1] = "hello!"
>> >>
>> >> print(a) # [1, ['x', 'hello!'], 3]
>> >> print(b) # what will that print?
>> >>
>> >> Think twice before you answer. What is copied, what is referenced?
>>
>> > print(b) will print the original copy of a which b now references which
>is
>> > [1, ["x", "y"], 3]
>>
>> Uh, oh! You should have checked your work in the interpreter before
>> replying! Peter is being very tricky!! (At least for me...) Look again
>> at that list inside of a list and... [...]
>
>Ok, just tried it out.  In this example b=a and b=a[:] seem to yield the
>same results even after the change to a, which I do not understand.  Should
>not b be a copy of a and not reflect the change?

Because is it a _shallow_ copy. Doing this:

  b = a[:]

produces a new list, referenced by "b", with the _same_ references in it as 
"a". a[1] is a reference to this list:

  ["x", "y"]

b[1] is a reference to the _same_ list. So "a[:]" makes what is called a 
"shallow" copy, a new list with references to the same deeper structure.

So this:

  a[1][1] = "hello!"

affects the original x-y list, and both "a" and "b" reference it, so printing 
either shows the change.

By contrast, this:

  a[1] = ["x", "hello"]

_replaces_ the reference in "a" with a reference to a new, different, list.

Sometimes you want a "deep" copy, where "b" would have got a copy of the 
iriginal x-y list. See the "copy" module's "deepcopy" function, which supplies 
this for when it is needed:

  https://docs.python.org/3/library/copy.html#copy.deepcopy

Cheers,
Cameron Simpson <cs at zip.com.au>

Draw little boxes with arrows.  It helps.       - Michael J. Eager

From robertvstepp at gmail.com  Sun Apr 19 06:26:02 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 18 Apr 2015 23:26:02 -0500
Subject: [Tutor] lists, name semantics
In-Reply-To: <20150419040806.GA80371@cskk.homeip.net>
References: <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
 <20150419040806.GA80371@cskk.homeip.net>
Message-ID: <CANDiX9+hHNRJ4_vmZzBEU51jNUGinpx78PVU2VaCLqVagTt+fA@mail.gmail.com>

On Sat, Apr 18, 2015 at 11:08 PM, Cameron Simpson <cs at zip.com.au> wrote:

> Sometimes you want a "deep" copy, where "b" would have got a copy of the
> iriginal x-y list. See the "copy" module's "deepcopy" function, which
> supplies this for when it is needed:
>
>  https://docs.python.org/3/library/copy.html#copy.deepcopy

In this reference, part of it states:

"Two problems often exist with deep copy operations that don?t exist
with shallow copy operations:

Recursive objects (compound objects that, directly or indirectly,
contain a reference to themselves) may cause a recursive loop.
Because deep copy copies everything it may copy too much, e.g.,
administrative data structures that should be shared even between
copies."

If I am understanding things correctly, should not that last sentence
read instead:

"...structures that should *not* be shared even between copies." ???

-- 
boB

From cs at zip.com.au  Sun Apr 19 07:09:51 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Sun, 19 Apr 2015 15:09:51 +1000
Subject: [Tutor] lists, name semantics
In-Reply-To: <CANDiX9+hHNRJ4_vmZzBEU51jNUGinpx78PVU2VaCLqVagTt+fA@mail.gmail.com>
References: <CANDiX9+hHNRJ4_vmZzBEU51jNUGinpx78PVU2VaCLqVagTt+fA@mail.gmail.com>
Message-ID: <20150419050951.GA40934@cskk.homeip.net>

On 18Apr2015 23:26, boB Stepp <robertvstepp at gmail.com> wrote:
>On Sat, Apr 18, 2015 at 11:08 PM, Cameron Simpson <cs at zip.com.au> wrote:
>> Sometimes you want a "deep" copy, where "b" would have got a copy of the
>> iriginal x-y list. See the "copy" module's "deepcopy" function, which
>> supplies this for when it is needed:
>>
>>  https://docs.python.org/3/library/copy.html#copy.deepcopy
>
>In this reference, part of it states:
>
>"Two problems often exist with deep copy operations that don?t exist
>with shallow copy operations:
>
>Recursive objects (compound objects that, directly or indirectly,
>contain a reference to themselves) may cause a recursive loop.
>Because deep copy copies everything it may copy too much, e.g.,
>administrative data structures that should be shared even between
>copies."
>
>If I am understanding things correctly, should not that last sentence
>read instead:
>
>"...structures that should *not* be shared even between copies." ???

No, the text is correct.

Suppose you have a graph of objects where some single object A is referenced in 
mulitple places:

      /--> O1 ----v
  G <              A
      \--> O2 ----^

If I make a deepcopy of "G" I want this:

          /--> O1copy ----v
  Gcopy <                  Acopy
          \--> O2copy ----^

i.e. a _single_ copy "Acopy" of "A", again referenced from 2 places in the 
copied graph.

Without deepcopy()'s object tracking you would get something like this:

          /--> O1copy ----> Acopy1
  Gcopy <
          \--> O2copy ----> Acopy2

i.e. two distinct copies of "A". Changes to "Acopy1" would not affect "Acopy2".

Cheers,
Cameron Simpson <cs at zip.com.au>

They said it couldn't be done/they said nobody could do it/
But he tried the thing that couldn't be done!/He tried - and he couldn't do it.

From cs at zip.com.au  Sun Apr 19 07:24:07 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Sun, 19 Apr 2015 15:24:07 +1000
Subject: [Tutor] lists, name semantics
In-Reply-To: <20150419050951.GA40934@cskk.homeip.net>
References: <20150419050951.GA40934@cskk.homeip.net>
Message-ID: <20150419052407.GA63795@cskk.homeip.net>

On 19Apr2015 15:09, Cameron Simpson <cs at zip.com.au> wrote:
>On 18Apr2015 23:26, boB Stepp <robertvstepp at gmail.com> wrote:
>>On Sat, Apr 18, 2015 at 11:08 PM, Cameron Simpson <cs at zip.com.au> wrote:
>>>Sometimes you want a "deep" copy, where "b" would have got a copy of the
>>>iriginal x-y list. See the "copy" module's "deepcopy" function, which
>>>supplies this for when it is needed:
>>>
>>> https://docs.python.org/3/library/copy.html#copy.deepcopy
>>
>>In this reference, part of it states:
>>
>>"Two problems often exist with deep copy operations that don?t exist
>>with shallow copy operations:
>>
>>Recursive objects (compound objects that, directly or indirectly,
>>contain a reference to themselves) may cause a recursive loop.
>>Because deep copy copies everything it may copy too much, e.g.,
>>administrative data structures that should be shared even between
>>copies."
>>
>>If I am understanding things correctly, should not that last sentence
>>read instead:
>>
>>"...structures that should *not* be shared even between copies." ???
>
>No, the text is correct.

Um, my explaination was incomplete.

The first sentence quoted explains why it is necessary for deepcopy keep track 
of copied objects in order to correctly duplicate objects just once instead of 
twice or more, let alone in an unbounded way if there is a loop (A->B->C->A).  
It does this with a "memo" dictionary of already copied objects so it can know 
them when it sees them again.

The second sentence "Because deep copy copies everything it may copy too much, 
e.g., administrative data structures that should be shared even between copies" 
is an issuewhich is addressed lower down when mentioning the __copy_ and 
__deepcopy__ methods. And it is not necessarily obvious.

Suppose you've got a data structure of objects, which should broadly be copied.  
However, _internally_, these objects may use some external facility. Further, 
suppose that facility can't be copied; perhaps it is a reference to a databse 
or something built around something like that. Like this:

  G -> A
    -> B
    -> _open_database

When you deepcopy that data sctructure you want to copy everything, but _not_ 
copy the external facility object. So for the above example, after the deepcopy 
you want this:

  Gcopy -> Acopy
        -> Bcopy
        -> _open_database

i.e. the same reference to the database, but copies of "A" and "B".

If you give "G"'s class a .__deepcopy__ method, then that will be called by 
deepcopy() to make a copy of "G" by calling "G.__deepcopy__(memodict)". And G's 
class will define its __deepcopy__ method to copy "A" and "B" but not 
"_open_database".

Most classes do not need this and deepcopy() just copies everything.

Does this clarify things?

Cheers,
Cameron Simpson <cs at zip.com.au>

No wonder these courtroom dramas are so popular. Half the population are
lawyers, judges, or some other kind of criminal.        - Jake Vest 1986

From cybervigilante at gmail.com  Sun Apr 19 03:56:41 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sat, 18 Apr 2015 18:56:41 -0700
Subject: [Tutor] sample dictionairies
Message-ID: <CALRAYNVC1rgTM=qGzcayYFqVKgcSQwoF+7MBxvsBgnqJ77JUsQ@mail.gmail.com>

Where could I download Python sample dictionaries on different subjects.
They're hard to type and I can only do small, limited ones to practice with.

-- 
Jim

The probability of a piano falling on my head is 50%. After it falls on my
head the probability is 100%. My confidence in the piano hitting my head
has increased.
This is Bayesian statistics in a nutshell.

From ben+python at benfinney.id.au  Sun Apr 19 10:28:28 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Sun, 19 Apr 2015 18:28:28 +1000
Subject: [Tutor] sample dictionairies
References: <CALRAYNVC1rgTM=qGzcayYFqVKgcSQwoF+7MBxvsBgnqJ77JUsQ@mail.gmail.com>
Message-ID: <85383wr07n.fsf@benfinney.id.au>

Jim Mooney <cybervigilante at gmail.com> writes:

> Where could I download Python sample dictionaries on different
> subjects.

I don't know what yoy mean by the ?subject? of a dictionary.

A Python dict is a data structure. Its values can be any collection of
Python objects.

Is the ?subject? of a dictionary its meaning? Its meaning is entirely up
to whoever wrote it and whoever reads it.

So I have to guess that you mean something else. What do you mean by
?dictionaries on different subjects??

-- 
 \            ?Technology is neither good nor bad; nor is it neutral.? |
  `\                       ?Melvin Kranzberg's First Law of Technology |
_o__)                                                                  |
Ben Finney


From alan.gauld at btinternet.com  Sun Apr 19 10:45:00 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Apr 2015 09:45:00 +0100
Subject: [Tutor] sample dictionairies
In-Reply-To: <CALRAYNVC1rgTM=qGzcayYFqVKgcSQwoF+7MBxvsBgnqJ77JUsQ@mail.gmail.com>
References: <CALRAYNVC1rgTM=qGzcayYFqVKgcSQwoF+7MBxvsBgnqJ77JUsQ@mail.gmail.com>
Message-ID: <mgvpua$g4l$1@ger.gmane.org>

On 19/04/15 02:56, Jim Mooney wrote:
> Where could I download Python sample dictionaries on different subjects.

Like Ben I don't understand what you mean by subject.
However,...

> They're hard to type and I can only do small, limited ones to practice with.

If you just want a large dictionary grab a plain text ebook(*)
and write a short bit of code to extract all the unique words
into a list. Then iterate over that list and create a
dictionary using the words as keys and their length as
values.

If you start with something like the bible then that should give
you a reasonably big dictionary for relatively little typing.

(*)
Project Gutenberg has dozens of free examples.
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From steve at pearwood.info  Sun Apr 19 12:42:46 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 19 Apr 2015 20:42:46 +1000
Subject: [Tutor] sample dictionairies
In-Reply-To: <CALRAYNVC1rgTM=qGzcayYFqVKgcSQwoF+7MBxvsBgnqJ77JUsQ@mail.gmail.com>
References: <CALRAYNVC1rgTM=qGzcayYFqVKgcSQwoF+7MBxvsBgnqJ77JUsQ@mail.gmail.com>
Message-ID: <20150419104246.GB5663@ando.pearwood.info>

On Sat, Apr 18, 2015 at 06:56:41PM -0700, Jim Mooney wrote:

> Where could I download Python sample dictionaries on different subjects.
> They're hard to type and I can only do small, limited ones to practice with.

I don't think you can download Python dicts. It would be a bit hard, 
since Python dicts exist only while the Python interpreter is running. 
Normally data is provided in text form, and then read from a file and 
converted into a dict or list as needed.

If you search the internet, you will find lots of places that you can 
download data on various topics. You can start at Wikidata:

https://www.wikidata.org/
?http://en.wikipedia.org/wiki/Wikidata


But for simple experiments, there is an easier solution. Instead of 
typing the dicts yourself, create them programmatically!

Let's say I want a dict like:

{'a': 1, 'b': 2, 'c': 3, ... 'z': 26}

That would be a PITA to type out in full. But I can do this:

import string
pairs = zip(string.ascii_lowercase, range(1, 27))
d = dict(pairs)

zip is invaluable for this sort of thing, because it takes two (or more) 
independent sequences and "zips" them together into a single sequence of 
pairs. So zip('abcde...z', [1, 2, 3, 4, 5, ..., 26]) ends up as the 
sequence [('a', 1), ('b', 2), ('c', 3), ... ] which is exactly what 
dict() needs to build a dictionary.

Here's another example:

from random import random
d = dict((n, random()) for n in range(10000))

This uses a *generator expression* to provide a sequence of (key, value) 
pairs, where the keys are numbers 0, 1, 2, ... and the values are random 
floats. You might have seen list comprehensions:

[x**2+1 for x in range(15)]

for example. Generator expressions are similar, except they don't 
calculate the items up front into a list, they calculate them lazily 
only when needed. To turn a list comprehension into a generator 
expression, change the outer-most square brackets [ ] into round 
brackets:

(x**2+1 for x in range(15))

In Python 3, we also have *dict comprehensions* which are based on list 
comprehensions:

d = {n: random() for n in range(10000)}

So my advice is this: rather than look for somebody to provide you with 
ready-made dicts, learn how to assemble them yourself!

# dict of {name: age} pairs
names = 'Fred Wilma Barney Betty Homer Marge'.split()
ages = [35, 31, 34, 36, 30]
d = dict(zip(name, ages))


-- 
Steve

From davea at davea.name  Sun Apr 19 13:47:59 2015
From: davea at davea.name (Dave Angel)
Date: Sun, 19 Apr 2015 07:47:59 -0400
Subject: [Tutor] lists, name semantics
In-Reply-To: <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
 <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
 <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>
Message-ID: <553395EF.3020708@davea.name>

On 04/19/2015 12:07 AM, boB Stepp wrote:

.....
Before Peter changed one of these
> changeable objects, he had:
>
> a = [1, ["x", "y"], 3]
> b = a[:]
>
> Now BOTH a[1] and b[1] now identify the location of the inner list
> object, ["x", "y"] . Apparently, Python, in its ever efficient memory
> management  fashion, when it creates the new object/piece of data
> a[:], it sees no need to duplicate the inner list object, ["x", "y"],
> but instead creates another identifier/pointer/reference to this
> object's location. But since this inner list object is mutable, when
> you change "y" to "hello!" in b, you also change it in a because both
> a[1][1] and b[1][1] reference/point to the exact same storage location
> where this element of the inner list is actually stored.
>
> I hope this is helpful, and, if there are any misstepps, that when
> they are revealed both of our understandings will be enhanced!
>

Some of your knowledge of other languages is leaking into your 
explanation.  When we talk of the language Python, we need to 
distinguish between how CPython happens to be implemented, how other 
Python implementations happen to be created, and how C++ (for example) 
implements similar things.  Some of the above use pointers, some do not. 
  The language Python does not.

So especially when talking of inner lists, we need to clarify a few things.

An object has an identity, not a location.  That identity can be checked 
with the 'is' operator, or the id() function.  But it exists all the time.

Variables, as you say, do not contain an object, they reference it.  And 
the formal term for that is binding.  A name is bound to an object, to 
one object, at a time.

Now some objects have attributes, which is to say names, and those 
attributes are bound to other objects.  So if we define a class, and 
have an instance of that class, and the instance has attributes, we can 
do something like:
     obj.inst_name

and get the particular attribute.

Still other objects have unnamed bindings.  The canonical example is a 
list.  A list object has a bunch of bindings to other objects.  Even 
though each  binding doesn't have a specific name, it nevertheless 
exists.  And in this case we use integers to specify which of those 
bindings we want to follow.  And we use a special syntax (the square 
bracket) to indicate which of these we want.

So let's take the simplest example:

mylist = ["a", "b"]

the name mylist is bound to a list object, which has two numbered 
bindings, called 0 and 1.  That object's  [0] binding is to a separate 
object "a".  And the [1] binding is to a separate object "b"

There is another shorthand called a slice, which looks like [start, len, 
step] which lets us construct a *new* list from our list.  And using 
defaults for all three terms lets us copy the list.  But let's look at 
what the copy means:

newlist = mylist[:]
         -->  mylist[0, 2, 1]

This constructs a new list from the present one, where the zeroth 
location is bound to whatever object the first list's zeroth location 
was bound to.  And so on for the oneth location, the twoth, etc.

Only one new list object is built, and no new objects are made for it. 
It just gets new bindings to the same things the first list had.

At this point, it should be clear what a shallow copy means.  If the 
original list's oneth item was a binding to another list object, *that* 
list object does NOT get copied.

I don't like the term "inner list",  but I don't know if it's incorrect. 
  It's just misleading, since to the slice operation, the fact that it's 
a list is irrelevant.  It's just an object whose binding is to be copied.

-- 
DaveA

From lac at openend.se  Sun Apr 19 10:16:24 2015
From: lac at openend.se (Laura Creighton)
Date: Sun, 19 Apr 2015 10:16:24 +0200
Subject: [Tutor] sample dictionairies
In-Reply-To: Message from Jim Mooney <cybervigilante@gmail.com> of "Sat,
 18 Apr 2015 18:56:41 -0700."
 <CALRAYNVC1rgTM=qGzcayYFqVKgcSQwoF+7MBxvsBgnqJ77JUsQ@mail.gmail.com>
References: <CALRAYNVC1rgTM=qGzcayYFqVKgcSQwoF+7MBxvsBgnqJ77JUsQ@mail.gmail.com>
Message-ID: <201504190816.t3J8GOho021852@fido.openend.se>

In a message of Sat, 18 Apr 2015 18:56:41 -0700, Jim Mooney writes:
>Where could I download Python sample dictionaries on different subjects.
>They're hard to type and I can only do small, limited ones to practice with.
>
>-- 
>Jim

For randomly generating data which look like addresses, I use:
http://www.generatedata.com/

While it has 'export to programming language' as a feature, Python isn't
one of the supported languages.  Which is fine.  It can export into comma
separated values, and writing a Python program to construct a dictionary
from comma separated values is easy.

Laura


From niyanaxx95 at gmail.com  Sun Apr 19 17:25:59 2015
From: niyanaxx95 at gmail.com (niyanaxx95 at gmail.com)
Date: Sun, 19 Apr 2015 15:25:59 +0000
Subject: [Tutor] =?utf-8?q?=3DLinked_List_Using_Map?=
In-Reply-To: <20150419030232.GA5663@ando.pearwood.info>
References: <55314ca1.c7628c0a.6f1c.ffffd77a@mx.google.com>
 <55314cc2.9512370a.1868.ffffd2c5@mx.google.com>,
 <20150419030232.GA5663@ando.pearwood.info>
Message-ID: <5533c98c.0514370a.2a4e.0d96@mx.google.com>

Thank You Steven for your great help!!!! You really helped me to understand my assignment more as well as what maps and linked lists are.  

I used your guidance and came up with my full code. 

May you take a look and let me know what needs to be changed? Thank you in advance.



class Node:
    def __init__( self, key, value, next = None ) :
        self.key = key
        self.value = value
        self.next = next
    
    def getItem( self ) :
        return self.key
    
    def getNext( self ) :
        return self.next
    
    def setItem( self, item ) :
        self.next = next
        
    def setNext( self, next ) :
        self.next = next


class Map:
    
    def __init__( self, contents = []) :
        self.first = None
        self.last = self.first
        self.numItems = 0
        
         # traverse the linked list
        node = self.first
        while node is not None:
            print("key = %s, value = %s" % (node.key, node.value))
            node = node.next
        
        # Add new node to the end 
        node = self.first
        if node is None:
            self.first = Node("the key", "some value")
        else:
            while node.next is not None:
                node = node.next
            node.next = Node("the key", "some value")
        
            
    def length( self ) :
        if node.next == Node("the key", "some value"):
            self.numItems = self.numItems + 1
        else:
            self.numItems = self.numItems - 1
        return self.numItems
    
    def contains() :
        node = self.first
        while node is not None:
            if node.key == key:
                return True
            else:
                return False
    
    def setitem( self, key, value ) :
        node = self.first
        while node is not None:
            if key in self.key :
                        pos = self.key.index(key)
                        node.value[pos] = value
                        return
            else:
                        node = node.next          
    
    def getitem( self, key ) :
        node = self.first
        while node is not None:
            assert key in self.key
            keypos = self.key.index(key)
            return node.value[keypos]
        
    # Clears or empties the map by removing all key/value pairs
    def clear( self ):
        return self.first == None
    
    # Returns a list containing the keys stored in the map.
    def keys( self ):
        return self.key
    
    # Returns a list contain the values stored in the map.
    def values( self ):
        return self.value
    
    
    # Returns a string representation of the map in the following format:{k1:v1, k2:v2, ..., kN:vN}
    def __repr__( self ):
        return "{%s}" % (", ".join(["%s:%s" % (k,v) for k, v in zip(self._key, self._value)]))
    
    
    # Returns the minimum key in the map. The map cannot be empty.
    def min(self, key ):
        node = self.first
        while node is not None and self.first == None:
            pass
    
    # Returns the maxiumum key in the map. The map cannot be empty.
    def max( self, key ):
        node =  self.first
        while node is not None and self.first == None:
            pass
    
    # Create a new linked list that contains the same entries as the origninal
    def copy( self ):
        if self.next is None:
            return self.value
        else:
            return self.value, self.next.copy()






Sent from Windows Mail





From: Steven D'Aprano
Sent: ?Saturday?, ?April? ?18?, ?2015 ?11?:?02? ?PM
To: tutor at python.org
Cc: Ni'Yana Morgan





Hello Ni'Yana, and welcome!

On Fri, Apr 17, 2015 at 06:11:00PM +0000, niyanaxx95 at gmail.com wrote:

> Hello I need guidance trying to solve my assignment. I am completely 
> lost when using maps with linked lists. I understand linked lists 
> though. May someone work with me?

We will not do your homework, but perhaps we can guide you.

Thank you for showing your code. It looks like you have already made a 
lot of progress.

Unfortunately, the one thing you did not tell us is what part of the 
assignment you are having problems with! It looks like you have done 
most of the work correctly so far, so what part is giving you trouble?

A few comments on your code below:


> class Node:
>     def __init__( self, item, next = None ) :
>         self.item = item
>         self.next = next
>     def getItem( self ) :
>         return self.item
>     def getNext( self ) :
>         return self.next
>     def setItem( self, item ) :
>         self.item = item
>     def setNext( self, next ) :
>         self.next = next

Your Node class looks straightforward, but it doesn't match the 
requirements. The requirement for the Map is that it must have key:value 
pairs. But your Node doesn't have two data fields, it only has one! So 
you cannot give the Node both a key and a value.

Your Node class needs to start like this:

class Node:
    def __init__(self, key, value, next=None):
        self.key = key
        self.value = value
        self.next = next


That will help get the Map class right. See my comments below.


> class Map:
>     def __init__( self, contents = []) :
>         self.first = LinkedList.Node(None, None)

First problem: you have added code which is not part of the 
specifications. The assignment says that calling Map() returns a new 
empty map. It says nothing about Map([1, 2, 3]). Get rid of the 
"contents" argument, it is not required. Once you get rid of that, the 
"for e in contents" loop is not required. Get rid of it!

Second problem: LinkedList is not defined anywhere. What is it?

The easiest way for this to work is to put the None class and the Map 
class in the same file, and then you can just say:

        self.first = Node(None, None)

without worrying about the name of the file. Java has a rule that each 
class, no matter how tiny, must go in its own file, but Python does not
have such a rule. Related classes may go in the same file.

Third problem: your assignment to self.first is wrong! That gives 
the Map a single item, not zero items!

An empty linked list will be represented here by just None alone.

        self.first = None

You then traverse the linked list like this:


    node = self.first
    while node is not None:
        print("key = %s, value = %s" % (node.key, node.value))
        node = node.next

which will print all the keys and values in the map.

To add a new node to the end, you do this:

    node = self.first
    # The empty Map case is special.
    if node is None:
        self.first = Node("the key", "some value")
    else:
        while node.next is not None:
            node = node.next
        # Now we are at the end of the linked list.
        # Add a new node.
        node.next = Node("the key", "some value")

>         self.last = self.first
>         self.numItems = 0
>         for e in contents:
>             self.append(e)
>             
>     def __len__( self ) :
>         count = 0
>         while self != None:
>             count +=1
>             self = self.next
>         return count

I don't think that this will do what your assignment asks. 

The first problem is that your assignment says that your Map must have a 
method called `length` which returns the number of items. Your Map class 
has no method called `length`, instead it uses the Python special 
__len__ method.

I think you need to change the name of this __len__ method to length. It 
is still be buggy (have you tested it?) but at least it will do what the 
assignment says.

Let us think about how to implement this length method. It is actually 
very easy! Your Map class already has a counter which tell you how many 
items are in the map, and it is initialised with:

        self.numItems = 0

so length is easy:

def length(self):
    return self.numItems


Now all you need to do is make sure that every time you add a node to 
the Map, add 1 to numItems, and every time you delete a node, you 
subtract 1.


>     def contains() :
>         pass

I assume this is just a stub which is not finished yet.

The contains method just needs to walk the linked list and look for the 
key. I showed you code above that walks the linked list printing keys 
and values. Instead of printing, you compare the node's key to the key 
you are looking for, and if they are equal, return True:

        while node is not None:
            if node.key == key:
                return True


If you reach the end of the linked list without finding the key, you 
have to return False.


Both your __setitem__ and __getitem__ methods also ignore what the 
assignment says. The assignment wants methods called `setitem` and 
`getitem`, not the special Python double-underscore methods. So you need 
to change their names, then test them.

Also, they fail to do what the assignment says. Read the requirements:

getitem(key): Returns the value associated with the given key, which 
must exist.

Does your __getitem__ method take a key as argument? No it does not, it 
takes an index!

getitem needs to take a single argument, the key. It then walks the 
linked list (as I showed you above), comparing the node's key to the 
wanted key. If they are equal, you then return node.value. If they are 
not equal, go on to the next node.

If you run out of nodes before finding the key, that is an error.

setitem needs to take two arguments, a key and a value. You then walk 
the linked list (again!) and compare the node's key to the wanted key. 
If they are equal, you set the node's value to the new value:

    node.value = value

and return.

If you run out of nodes, you add a new node at the end.

Remember what I said about incrementing the counter!

By this time, you should see a pattern. Nearly all these methods 
demonstrate the same sort of procedure: you walk the linked list, 
looking at each node in turn:

    node = self.first
    while node is not None:
        do_something_with(node)



-- 
Steve

From alan.gauld at btinternet.com  Sun Apr 19 20:18:43 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Apr 2015 19:18:43 +0100
Subject: [Tutor] =Linked List Using Map
In-Reply-To: <5533c98c.0514370a.2a4e.0d96@mx.google.com>
References: <55314ca1.c7628c0a.6f1c.ffffd77a@mx.google.com>
 <55314cc2.9512370a.1868.ffffd2c5@mx.google.com>,
 <20150419030232.GA5663@ando.pearwood.info>
 <5533c98c.0514370a.2a4e.0d96@mx.google.com>
Message-ID: <mh0ri1$1pi$1@ger.gmane.org>

On 19/04/15 16:25, niyanaxx95 at gmail.com wrote:

> May you take a look and let me know what needs to be changed? Thank you in advance.

The node code looks OK.

> class Map:
>

Read through your init method, remembering that it only gets calledv 
once when the Map is created.

>      def __init__( self, contents = []) :
>          self.first = None
>          self.last = self.first
>          self.numItems = 0

So far so good.

>           # traverse the linked list

But there is no list at this point. You just set it to None.

>          node = self.first
>          while node is not None:
>              print("key = %s, value = %s" % (node.key, node.value))
>              node = node.next

So that block does nothing.

>          # Add new node to the end
>          node = self.first
>          if node is None:

And you know the node is NBone so you don;t need a test

>              self.first = Node("the key", "some value")

This is the only meaningful line in the method so far.
Although I suspect the key and value need to be fetched
from somewhere so that they are useful.

Also shouldn't you increment the numItems counter
about now?

>          else:
>              while node.next is not None:
>                  node = node.next
 >              node.next = Node("the key", "some value")

This else block never gets executed either since
the node is always None.

Most of the init method can be deleted.



>      def length( self ) :
>          if node.next == Node("the key", "some value"):
>              self.numItems = self.numItems + 1
>          else:
>              self.numItems = self.numItems - 1
>          return self.numItems

This is just wrong. You keep incrementing numItems but never reset it.
Also you keep creating a new Node then throwing it away.
If you keep numItems up to date as you add and delete
items all you need do is return nnumItems.

>      def contains() :
>          node = self.first
>          while node is not None:
>              if node.key == key:
>                  return True

where does key come from? I assume it should be a
parameter of the method?

>              else:
>                  return False

Thids returns False after the first test. What if the node
you are looking for is further down the list? You need to
exdent (dedent?) this section till its outside the while loop.

>      def setitem( self, key, value ) :
>          node = self.first
>          while node is not None:
>              if key in self.key :

Where does self.key come from? Its not set in the init() method.
Also if its a collection shouldn't it be called keys?

>                          pos = self.key.index(key)
>                          node.value[pos] = value
>                          return

If pos is the index into the list of keys I assume valyue should be a 
corresponding list of values? In which case call it values not value.
But if you are using a ppair of lists to hold the keys and values what 
is the linked list of nodes for? They seem pointless.
But the value(s) dseem to be attached to the node? But the keys are 
attached tgto the Maop(self)? I'm not sure what you are trying to do here.

>              else:
>                          node = node.next
>
>      def getitem( self, key ) :
>          node = self.first
>          while node is not None:
>              assert key in self.key
>              keypos = self.key.index(key)
>              return node.value[keypos]

The while loop only goes as far as the first node.
Does every node contain a list of all the values?
That seems a bit wasteful?

>      # Clears or empties the map by removing all key/value pairs
>      def clear( self ):
>          return self.first == None

This returns a boolean result. Which is not what the
comment says it does.

>      # Returns a list containing the keys stored in the map.
>      def keys( self ):
>          return self.key
>
>      # Returns a list contain the values stored in the map.
>      def values( self ):
>          return self.value

But the values were attacheed to the nodes not self?

>      # Returns a string representation of the map in the following format:{k1:v1, k2:v2, ..., kN:vN}
>      def __repr__( self ):
>          return "{%s}" % (", ".join(["%s:%s" % (k,v) for k, v in zip(self._key, self._value)]))
>
>
>      # Returns the minimum key in the map. The map cannot be empty.
>      def min(self, key ):
>          node = self.first
>          while node is not None and self.first == None:
>              pass

If you set node to be self.first how can they be different
as required by your while loop test?

>      # Returns the maxiumum key in the map. The map cannot be empty.
>      def max( self, key ):
>          node =  self.first
>          while node is not None and self.first == None:
>              pass

As above

>      # Create a new linked list that contains the same entries as the origninal
>      def copy( self ):
>          if self.next is None:
>              return self.value
>          else:
>              return self.value, self.next.copy()

This is returning a tuple not a copy of the original.

Can I suggest you try running your code before posting it. That
way you either have a set of error messages that you don't
understand how to fix, or you fix things so they run but it
doesn't quite do what you want.

We call this testing in the trade and it's a really good idea.
In fact its a good idea to build your classes one method at
a time and test it until that one works before even trying to
write the other methods. That way you know where the
faults lie - in the code you just wrote!

There are all sorts of fancy testing tools you can use, but just 
starting the >>> interactive prompt, importing your class file,
creating some instances and calling the methods with different
values is a great starting point!

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From robertvstepp at gmail.com  Sun Apr 19 20:36:08 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 19 Apr 2015 13:36:08 -0500
Subject: [Tutor] lists, name semantics
In-Reply-To: <20150419052407.GA63795@cskk.homeip.net>
References: <20150419050951.GA40934@cskk.homeip.net>
 <20150419052407.GA63795@cskk.homeip.net>
Message-ID: <CANDiX9JTCLcw1HipH4H84wfRqcu1+uaq0rGsShwPorJAXStsdw@mail.gmail.com>

On Sun, Apr 19, 2015 at 12:24 AM, Cameron Simpson <cs at zip.com.au> wrote:
> On 19Apr2015 15:09, Cameron Simpson <cs at zip.com.au> wrote:
>>
>> On 18Apr2015 23:26, boB Stepp <robertvstepp at gmail.com> wrote:
>>>
>>> On Sat, Apr 18, 2015 at 11:08 PM, Cameron Simpson <cs at zip.com.au> wrote:

[...]

>>> "Two problems often exist with deep copy operations that don?t exist
>>> with shallow copy operations:
>>>
>>> Recursive objects (compound objects that, directly or indirectly,
>>> contain a reference to themselves) may cause a recursive loop.
>>> Because deep copy copies everything it may copy too much, e.g.,
>>> administrative data structures that should be shared even between
>>> copies."
>>>
>>> If I am understanding things correctly, should not that last sentence
>>> read instead:
>>>
>>> "...structures that should *not* be shared even between copies." ???
>>
>>
>> No, the text is correct.
>
>
> Um, my explaination was incomplete.

[...]

> The second sentence "Because deep copy copies everything it may copy too
> much, e.g., administrative data structures that should be shared even
> between copies" is an issuewhich is addressed lower down when mentioning the
> __copy_ and __deepcopy__ methods. And it is not necessarily obvious.
>
> Suppose you've got a data structure of objects, which should broadly be
> copied.  However, _internally_, these objects may use some external
> facility. Further, suppose that facility can't be copied; perhaps it is a
> reference to a databse or something built around something like that. Like
> this:
>
>  G -> A
>    -> B
>    -> _open_database
>
> When you deepcopy that data sctructure you want to copy everything, but
> _not_ copy the external facility object. So for the above example, after the
> deepcopy you want this:
>
>  Gcopy -> Acopy
>        -> Bcopy
>        -> _open_database
>
> i.e. the same reference to the database, but copies of "A" and "B".

Ah! This example clarifies things for me. This provides a specific
context for  the phrase, "...that should be shared even between
copies..." That now makes sense.

> If you give "G"'s class a .__deepcopy__ method, then that will be called by
> deepcopy() to make a copy of "G" by calling "G.__deepcopy__(memodict)". And
> G's class will define its __deepcopy__ method to copy "A" and "B" but not
> "_open_database".
>
> Most classes do not need this and deepcopy() just copies everything.
>
> Does this clarify things?

Very much! Thanks!

-- 
boB

From robertvstepp at gmail.com  Sun Apr 19 21:08:41 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 19 Apr 2015 14:08:41 -0500
Subject: [Tutor] lists, name semantics
In-Reply-To: <553395EF.3020708@davea.name>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
 <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
 <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>
 <553395EF.3020708@davea.name>
Message-ID: <CANDiX9+cMvUWZsY98cMbT=jpR+w1o03RoEgbg4rT1HsDGGadzg@mail.gmail.com>

On Sun, Apr 19, 2015 at 6:47 AM, Dave Angel <davea at davea.name> wrote:
> On 04/19/2015 12:07 AM, boB Stepp wrote:

[...]

>> I hope this is helpful, and, if there are any misstepps, that when
>> they are revealed both of our understandings will be enhanced!
>>
>
> Some of your knowledge of other languages is leaking into your explanation.
> When we talk of the language Python, we need to distinguish between how
> CPython happens to be implemented, how other Python implementations happen
> to be created, and how C++ (for example) implements similar things.  Some of
> the above use pointers, some do not.  The language Python does not.

I actually was being deliberately  *imprecise* in my use of technical
terminology.  But I see below that there are some nuances I need to
learn...

> So especially when talking of inner lists, we need to clarify a few things.
>
> An object has an identity, not a location.  That identity can be checked
> with the 'is' operator, or the id() function.  But it exists all the time.

But the object, in order to exist, must be stored in RAM somewhere,
doesn't it? Or is the real point that we are adding an abstraction
layer so we don't even have to think about where objects are
physically stored in RAM? So I am the object referenced by "boB" and
we don't care what my precise (x, y, z) coordinates are relative to
the planet Earth. If we need to find me or modify me we use my label,
"boB", to access me?

> Variables, as you say, do not contain an object, they reference it.  And the
> formal term for that is binding.  A name is bound to an object, to one
> object, at a time.
>
> Now some objects have attributes, which is to say names, and those
> attributes are bound to other objects.  So if we define a class, and have an
> instance of that class, and the instance has attributes, we can do something
> like:
>     obj.inst_name
>
> and get the particular attribute.
>
> Still other objects have unnamed bindings.  The canonical example is a list.
> A list object has a bunch of bindings to other objects.  Even though each
> binding doesn't have a specific name, it nevertheless exists.  And in this
> case we use integers to specify which of those bindings we want to follow.
> And we use a special syntax (the square bracket) to indicate which of these
> we want.

Ah, "unnamed bindings" was the concept I was talking around. I
realized these were there and were referenced by the square bracket
syntax, but I did not know what to call the concept.

[...]

> At this point, it should be clear what a shallow copy means.  If the
> original list's oneth item was a binding to another list object, *that* list
> object does NOT get copied.
>
> I don't like the term "inner list",  but I don't know if it's incorrect.
> It's just misleading, since to the slice operation, the fact that it's a
> list is irrelevant.  It's just an object whose binding is to be copied.

So the real point here is that there are two distinct copying
mechanisms, deep and shallow. The "inner list" could just have been
any other type of object, though if it had been an immutable type it
would not have made Peter's original interesting point.

-- 
boB

From davea at davea.name  Sun Apr 19 23:05:23 2015
From: davea at davea.name (Dave Angel)
Date: Sun, 19 Apr 2015 17:05:23 -0400
Subject: [Tutor] lists, name semantics
In-Reply-To: <CANDiX9+cMvUWZsY98cMbT=jpR+w1o03RoEgbg4rT1HsDGGadzg@mail.gmail.com>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
 <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
 <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>
 <553395EF.3020708@davea.name>
 <CANDiX9+cMvUWZsY98cMbT=jpR+w1o03RoEgbg4rT1HsDGGadzg@mail.gmail.com>
Message-ID: <55341893.9020600@davea.name>

On 04/19/2015 03:08 PM, boB Stepp wrote:
> On Sun, Apr 19, 2015 at 6:47 AM, Dave Angel <davea at davea.name> wrote:
>> On 04/19/2015 12:07 AM, boB Stepp wrote:
>
> [...]
>
>>> I hope this is helpful, and, if there are any misstepps, that when
>>> they are revealed both of our understandings will be enhanced!
>>>
>>
>> Some of your knowledge of other languages is leaking into your explanation.
>> When we talk of the language Python, we need to distinguish between how
>> CPython happens to be implemented, how other Python implementations happen
>> to be created, and how C++ (for example) implements similar things.  Some of
>> the above use pointers, some do not.  The language Python does not.
>
> I actually was being deliberately  *imprecise* in my use of technical
> terminology.  But I see below that there are some nuances I need to
> learn...
>
>> So especially when talking of inner lists, we need to clarify a few things.
>>
>> An object has an identity, not a location.  That identity can be checked
>> with the 'is' operator, or the id() function.  But it exists all the time.
>
> But the object, in order to exist, must be stored in RAM somewhere,
> doesn't it?

Or in a swap file, a disk file, or some other media.

> Or is the real point that we are adding an abstraction
> layer so we don't even have to think about where objects are
> physically stored in RAM?

Somebody keeps track, but the address is not necessarily constant, and 
not necessarily stored in any references.  The references (bindings) are 
abstract, and the details are unimportant to the user.  For example, the 
jython system does not use addresses at all.  And an object gets moved 
around from time to time without its references knowing it.

> So I am the object referenced by "boB" and
> we don't care what my precise (x, y, z) coordinates are relative to
> the planet Earth. If we need to find me or modify me we use my label,
> "boB", to access me?

No, we use one of your many labels to find you.  And if no labels exist, 
you quietly cease to exist (garbage collection).  But understand that a 
"label" in this sense need not be some alpha string.  It might be a slot 
in some collection, like the way I described list.
>
>> Variables, as you say, do not contain an object, they reference it.  And the
>> formal term for that is binding.  A name is bound to an object, to one
>> object, at a time.
>>
>> Now some objects have attributes, which is to say names, and those
>> attributes are bound to other objects.  So if we define a class, and have an
>> instance of that class, and the instance has attributes, we can do something
>> like:
>>      obj.inst_name
>>
>> and get the particular attribute.
>>
>> Still other objects have unnamed bindings.  The canonical example is a list.
>> A list object has a bunch of bindings to other objects.  Even though each
>> binding doesn't have a specific name, it nevertheless exists.  And in this
>> case we use integers to specify which of those bindings we want to follow.
>> And we use a special syntax (the square bracket) to indicate which of these
>> we want.
>
> Ah, "unnamed bindings" was the concept I was talking around. I
> realized these were there and were referenced by the square bracket
> syntax, but I did not know what to call the concept.
>
> [...]
>
>> At this point, it should be clear what a shallow copy means.  If the
>> original list's oneth item was a binding to another list object, *that* list
>> object does NOT get copied.
>>
>> I don't like the term "inner list",  but I don't know if it's incorrect.
>> It's just misleading, since to the slice operation, the fact that it's a
>> list is irrelevant.  It's just an object whose binding is to be copied.
>
> So the real point here is that there are two distinct copying
> mechanisms, deep and shallow. The "inner list" could just have been
> any other type of object, though if it had been an immutable type it
> would not have made Peter's original interesting point.

The distinction between deep and shallow was already made, by better 
people than I.  I was trying to explain it in terms of a working model 
that would let you predict what will happen in each circumstance.  A 
slice only copies the bindings in the list, it doesn't care what they 
are bound to.  It's shallow because it's shallow.



-- 
DaveA

From robertvstepp at gmail.com  Mon Apr 20 00:23:13 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 19 Apr 2015 17:23:13 -0500
Subject: [Tutor] lists, name semantics
In-Reply-To: <55341893.9020600@davea.name>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
 <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
 <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>
 <553395EF.3020708@davea.name>
 <CANDiX9+cMvUWZsY98cMbT=jpR+w1o03RoEgbg4rT1HsDGGadzg@mail.gmail.com>
 <55341893.9020600@davea.name>
Message-ID: <CANDiX9KTk5g59xRJ7GntqTkXipj02OdZoXGt5Rt6YxR+LJevHg@mail.gmail.com>

On Sun, Apr 19, 2015 at 4:05 PM, Dave Angel <davea at davea.name> wrote:
> On 04/19/2015 03:08 PM, boB Stepp wrote:
>>

>> Or is the real point that we are adding an abstraction
>> layer so we don't even have to think about where objects are
>> physically stored in RAM?
>
>
> Somebody keeps track, but the address is not necessarily constant, and not
> necessarily stored in any references.  The references (bindings) are
> abstract, and the details are unimportant to the user.  For example, the
> jython system does not use addresses at all.  And an object gets moved
> around from time to time without its references knowing it.

The last sentence in this paragraph has me intrigued. Why would an
object, once it has been created, be moved? What practical benefit
does doing this give?

boB

From joel.goldstick at gmail.com  Mon Apr 20 00:28:56 2015
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Sun, 19 Apr 2015 18:28:56 -0400
Subject: [Tutor] lists, name semantics
In-Reply-To: <CANDiX9KTk5g59xRJ7GntqTkXipj02OdZoXGt5Rt6YxR+LJevHg@mail.gmail.com>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
 <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
 <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>
 <553395EF.3020708@davea.name>
 <CANDiX9+cMvUWZsY98cMbT=jpR+w1o03RoEgbg4rT1HsDGGadzg@mail.gmail.com>
 <55341893.9020600@davea.name>
 <CANDiX9KTk5g59xRJ7GntqTkXipj02OdZoXGt5Rt6YxR+LJevHg@mail.gmail.com>
Message-ID: <CAPM-O+yYEnO88b-n7o9Qy+=pWx7M4B+kGfrmKyhG__p4XK65hA@mail.gmail.com>

On Sun, Apr 19, 2015 at 6:23 PM, boB Stepp <robertvstepp at gmail.com> wrote:
> On Sun, Apr 19, 2015 at 4:05 PM, Dave Angel <davea at davea.name> wrote:
>> On 04/19/2015 03:08 PM, boB Stepp wrote:
>>>
>
>>> Or is the real point that we are adding an abstraction
>>> layer so we don't even have to think about where objects are
>>> physically stored in RAM?
>>
>>
>> Somebody keeps track, but the address is not necessarily constant, and not
>> necessarily stored in any references.  The references (bindings) are
>> abstract, and the details are unimportant to the user.  For example, the
>> jython system does not use addresses at all.  And an object gets moved
>> around from time to time without its references knowing it.
>
> The last sentence in this paragraph has me intrigued. Why would an
> object, once it has been created, be moved? What practical benefit
> does doing this give?
>
> boB

I'm guessing memory management.  You want to have large contiguous
blocks of memory available for large objects.  If a small object is
surrounded by available memory, you might want to move it to some
smaller empty spot.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Joel Goldstick
http://joelgoldstick.com

From davea at davea.name  Mon Apr 20 01:19:27 2015
From: davea at davea.name (Dave Angel)
Date: Sun, 19 Apr 2015 19:19:27 -0400
Subject: [Tutor] lists, name semantics
In-Reply-To: <CAPM-O+yYEnO88b-n7o9Qy+=pWx7M4B+kGfrmKyhG__p4XK65hA@mail.gmail.com>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
 <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
 <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>
 <553395EF.3020708@davea.name>
 <CANDiX9+cMvUWZsY98cMbT=jpR+w1o03RoEgbg4rT1HsDGGadzg@mail.gmail.com>
 <55341893.9020600@davea.name>
 <CANDiX9KTk5g59xRJ7GntqTkXipj02OdZoXGt5Rt6YxR+LJevHg@mail.gmail.com>
 <CAPM-O+yYEnO88b-n7o9Qy+=pWx7M4B+kGfrmKyhG__p4XK65hA@mail.gmail.com>
Message-ID: <553437FF.7070803@davea.name>

On 04/19/2015 06:28 PM, Joel Goldstick wrote:
> On Sun, Apr 19, 2015 at 6:23 PM, boB Stepp <robertvstepp at gmail.com> wrote:
>> On Sun, Apr 19, 2015 at 4:05 PM, Dave Angel <davea at davea.name> wrote:
>>> On 04/19/2015 03:08 PM, boB Stepp wrote:
>>>>
>>
>>>> Or is the real point that we are adding an abstraction
>>>> layer so we don't even have to think about where objects are
>>>> physically stored in RAM?
>>>
>>>
>>> Somebody keeps track, but the address is not necessarily constant, and not
>>> necessarily stored in any references.  The references (bindings) are
>>> abstract, and the details are unimportant to the user.  For example, the
>>> jython system does not use addresses at all.  And an object gets moved
>>> around from time to time without its references knowing it.
>>
>> The last sentence in this paragraph has me intrigued. Why would an
>> object, once it has been created, be moved? What practical benefit
>> does doing this give?
>>
>> boB
>
> I'm guessing memory management.  You want to have large contiguous
> blocks of memory available for large objects.  If a small object is
> surrounded by available memory, you might want to move it to some
> smaller empty spot.

Good answer.  The java jvm garbage collector is free to move blocks 
around to defrag the free space.

FWIW, I'm told the ID value used is a simple integer, that indexes a 
list containing the actual addresses.

So in this case, the binding value is an integer, not an address.

-- 
DaveA

From lac at openend.se  Mon Apr 20 00:52:40 2015
From: lac at openend.se (Laura Creighton)
Date: Mon, 20 Apr 2015 00:52:40 +0200
Subject: [Tutor] lists, name semantics
In-Reply-To: Message from boB Stepp <robertvstepp@gmail.com> of "Sun,
 19 Apr 2015 17:23:13 -0500."
 <CANDiX9KTk5g59xRJ7GntqTkXipj02OdZoXGt5Rt6YxR+LJevHg@mail.gmail.com>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
 <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
 <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>
 <553395EF.3020708@davea.name>
 <CANDiX9+cMvUWZsY98cMbT=jpR+w1o03RoEgbg4rT1HsDGGadzg@mail.gmail.com>
 <55341893.9020600@davea.name><CANDiX9KTk5g59xRJ7GntqTkXipj02OdZoXGt5Rt6YxR+LJevHg@mail.gmail.com>
Message-ID: <201504192252.t3JMqe5p022981@fido.openend.se>

In a message of Sun, 19 Apr 2015 17:23:13 -0500, boB Stepp writes:
>On Sun, Apr 19, 2015 at 4:05 PM, Dave Angel <davea at davea.name> wrote:
>> abstract, and the details are unimportant to the user.  For example, the
>> jython system does not use addresses at all.  And an object gets moved
>> around from time to time without its references knowing it.
>
>The last sentence in this paragraph has me intrigued. Why would an
>object, once it has been created, be moved? What practical benefit
>does doing this give?
>
>boB

One great reason is called 'garbage collection'.
We find all the objects we are using, stuff them someplace in
memory, and free up all the space they left.  Now we are free
to lay down a whole lot of other things, in  contiguous order.

When you want to go access an array, for instance, it matters'
a whole lot if you can actually say:

for x
    for y
    	tell_me (x,y)

rather than a lot of 'oops, I would love to tell you but when
I went to an address I got told, out space, go look over hear instead.



From lac at openend.se  Mon Apr 20 00:56:42 2015
From: lac at openend.se (Laura Creighton)
Date: Mon, 20 Apr 2015 00:56:42 +0200
Subject: [Tutor] lists, name semantics
In-Reply-To: Message from boB Stepp <robertvstepp@gmail.com> of "Sun,
 19 Apr 2015 17:23:13 -0500."
 <CANDiX9KTk5g59xRJ7GntqTkXipj02OdZoXGt5Rt6YxR+LJevHg@mail.gmail.com>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
 <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
 <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>
 <553395EF.3020708@davea.name>
 <CANDiX9+cMvUWZsY98cMbT=jpR+w1o03RoEgbg4rT1HsDGGadzg@mail.gmail.com>
 <55341893.9020600@davea.name><CANDiX9KTk5g59xRJ7GntqTkXipj02OdZoXGt5Rt6YxR+LJevHg@mail.gmail.com>
Message-ID: <201504192256.t3JMugI5023122@fido.openend.se>

In a message of Sun, 19 Apr 2015 17:23:13 -0500, boB Stepp writes:
>The last sentence in this paragraph has me intrigued. Why would an
>object, once it has been created, be moved? What practical benefit
>does doing this give?
>
boB

If you have more than enough memory in your system, you never do
this because there is never any need.  But if you would like to
lay down an array of x by y for the fastest access, you  would like
it to fit perfectly in memory.  Which can mean that the best you
can do is pick up a bunch of smaller objects, move them someplace
(anyplace) else, and then let your bigger object fit in memory
in contiguous space.

See 'garbage collection' for more useful ideas.

Laura


From lac at openend.se  Mon Apr 20 01:29:34 2015
From: lac at openend.se (Laura Creighton)
Date: Mon, 20 Apr 2015 01:29:34 +0200
Subject: [Tutor] lists, name semantics
In-Reply-To: Message from Dave Angel <davea@davea.name>
 of "Sun, 19 Apr 2015 19:19:27 -0400." <553437FF.7070803@davea.name>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
 <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
 <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>
 <553395EF.3020708@davea.name>
 <CANDiX9+cMvUWZsY98cMbT=jpR+w1o03RoEgbg4rT1HsDGGadzg@mail.gmail.com>
 <55341893.9020600@davea.name>
 <CANDiX9KTk5g59xRJ7GntqTkXipj02OdZoXGt5Rt6YxR+LJevHg@mail.gmail.com>
 <CAPM-O+yYEnO88b-n7o9Qy+=pWx7M4B+kGfrmKyhG__p4XK65hA@mail.gmail.com><553437FF.7070803@davea.name>
Message-ID: <201504192329.t3JNTYUa024447@fido.openend.se>

In a message of Sun, 19 Apr 2015 19:19:27 -0400, Dave Angel writes:
>Good answer.  The java jvm garbage collector is free to move blocks 
>around to defrag the free space.

Correct.

>FWIW, I'm told the ID value used is a simple integer, that indexes a 
>list containing the actual addresses.

Also correct for the majority of cases.  You would have to be
an expert in GC to care about when this is not correct, which is
what I happen to be,  but only a pedant would object to what you said.

>So in this case, the binding value is an integer, not an address.

Utterly wrong.  The binding value has to be an address.  All addresses
are integers.  I have no clue what you meant by this.  Please resubmit
and try again.  That some of the adresses are indirectly referred to
through a list means _nothing_.

Very puzzled, your brain is thinking wrong thoughts, but mostly
I can guess what is meant, here I cannot at all,

Sorry about that,
Laura


From alan.gauld at btinternet.com  Mon Apr 20 02:17:09 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Apr 2015 01:17:09 +0100
Subject: [Tutor] lists, name semantics
In-Reply-To: <201504192329.t3JNTYUa024447@fido.openend.se>
References: <CACrcdXufokeDEy==3+2khn1TJeZ-exSwFOVwW-wq45BnXzQH_g@mail.gmail.com>
 <mgsudl$rme$1@ger.gmane.org>
 <CACrcdXsA3hAh-jHP2ANPSatnMNw_iR=ZCSstJQ7qn0jZepTZDA@mail.gmail.com>
 <mgtjsg$h9j$1@ger.gmane.org>
 <CACrcdXuEGXs=pnzeKwS1U6PVrrgWCqLz6x7SbXSxg4nEs=h0Rw@mail.gmail.com>
 <CANDiX9LyG4kjmdcjfcjvfcZdKdhR6ur0JuX-V9QMf3XWMYtJWA@mail.gmail.com>
 <CACrcdXt8WJ7vG_cqCse553yK6VWJSyaOwX8oWGYHRYqiJ4=YtA@mail.gmail.com>
 <CANDiX9+vq72+=TksEV8OuWAdH=H4Xzjv=qwZCV4tseXK_O_mMw@mail.gmail.com>
 <553395EF.3020708@davea.name>
 <CANDiX9+cMvUWZsY98cMbT=jpR+w1o03RoEgbg4rT1HsDGGadzg@mail.gmail.com>
 <55341893.9020600@davea.name>
 <CANDiX9KTk5g59xRJ7GntqTkXipj02OdZoXGt5Rt6YxR+LJevHg@mail.gmail.com>
 <CAPM-O+yYEnO88b-n7o9Qy+=pWx7M4B+kGfrmKyhG__p4XK65hA@mail.gmail.com><553437FF.7070803@davea.name>
 <201504192329.t3JNTYUa024447@fido.openend.se>
Message-ID: <mh1gi3$man$1@ger.gmane.org>

On 20/04/15 00:29, Laura Creighton wrote:

>> So in this case, the binding value is an integer, not an address.
>
> Utterly wrong.  The binding value has to be an address.

I think it depends on how you define 'binding' value.
In Python binding is the connection between a name and an object.
So in a handle type system the binding between a name and object
is the objects handle, which is usually an integer. But the
address of the object is the thing the VM uses to fetch the actual 
object based on the handle. So we have two bindings at work.
The one the user sees between the name and the object (which
is the handle) and the one the VM uses between the handle
and the actual object, which is its address at that
particular moment in time. Its the VMs job to keep track
of how that second binding changes but the users view
of binding (the handle) never changes.

>  All addresses are integers.

Usually, but not always. In segmented architectures they
are tuples of integers, and in clustered Virtual Memory
implementations they may be vectors. But in modern
machines they usually resolve to an integer.

> I have no clue what you meant by this.  Please resubmit
> and try again.  That some of the adresses are indirectly referred to
> through a list means _nothing_.

It means a huge amount to the user(programmer), especially
if he/she erroneously tries to use a handle as an address.

And of course there is a third layer of abstraction here
because often times the "address" that compiler and VM writers
think of as the physical address is nothing of the sort
its just a bit of virtual space created by the OS
which then does another binding to the real RAM chips
(or magnetic tape, or optical drive or ferrite core or
whatever technology is providing the physical storage)

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From robertvstepp at gmail.com  Mon Apr 20 03:03:02 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 19 Apr 2015 20:03:02 -0500
Subject: [Tutor] OT: Is there a good book that covers the history/evolution
 of software? [Inspired by the thread: lists, name semantics]
Message-ID: <CANDiX9LjyeZMxz_pLJWU11924u6go6yGL-GbCS10RUs=BVY3Wg@mail.gmail.com>

In the beginning (I assume.) there was machine code and only machine
code. And I imagine this was not very good. Then I assume the next
step was assembler, which probably only moderated the (then) tedium of
coding. Then real high level languages were started to be developed,
and this was very good. And then there were various new programming
paradigms developed, and so on. What I am wondering is, is there a
good book that covers in relatively good detail how we started at the
most primitive level, machine code, and evolved to our current
wonderful cornucopia of languages, operating systems, etc.? As the
different threads reveal bits and pieces of the low level guts of
Python, I am becoming more and more fascinated about how all of this
is managed. Just the brief discussion of garbage collection details
going on I find quite interesting.

-- 
boB

From joel.goldstick at gmail.com  Mon Apr 20 03:26:08 2015
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Sun, 19 Apr 2015 21:26:08 -0400
Subject: [Tutor] OT: Is there a good book that covers the
 history/evolution of software? [Inspired by the thread: lists,
 name semantics]
In-Reply-To: <CANDiX9LjyeZMxz_pLJWU11924u6go6yGL-GbCS10RUs=BVY3Wg@mail.gmail.com>
References: <CANDiX9LjyeZMxz_pLJWU11924u6go6yGL-GbCS10RUs=BVY3Wg@mail.gmail.com>
Message-ID: <CAPM-O+w2sdM6z_MQxQ5sZ5Tp=yKtgYqbe7grfyj-z=ScdO8pGA@mail.gmail.com>

On Sun, Apr 19, 2015 at 9:03 PM, boB Stepp <robertvstepp at gmail.com> wrote:
> In the beginning (I assume.) there was machine code and only machine
> code. And I imagine this was not very good. Then I assume the next
> step was assembler, which probably only moderated the (then) tedium of
> coding. Then real high level languages were started to be developed,
> and this was very good. And then there were various new programming
> paradigms developed, and so on. What I am wondering is, is there a
> good book that covers in relatively good detail how we started at the
> most primitive level, machine code, and evolved to our current
> wonderful cornucopia of languages, operating systems, etc.? As the
> different threads reveal bits and pieces of the low level guts of
> Python, I am becoming more and more fascinated about how all of this
> is managed. Just the brief discussion of garbage collection details
> going on I find quite interesting.
>
> --
> boB

you might start here:
https://en.wikipedia.org/wiki/History_of_programming_languages

-- 
Joel Goldstick
http://joelgoldstick.com

From robertvstepp at gmail.com  Mon Apr 20 05:34:43 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 19 Apr 2015 22:34:43 -0500
Subject: [Tutor] How to close a Tkinter window from a different thread?
Message-ID: <CANDiX9LVDvbYoaVSzvLJeFpjqJrKf=Yt79nNnVtKXHbZ6ooKZA@mail.gmail.com>

I am not certain that my terminology is correct in the subject line.
Let me explain my issue.

Scenario A:
1) I start out inside a commercial software environment (Abbreviated
CSA henceforth).
2) I initiate a script in the CSA's scripting language.
3) This script calls an external Python script.com
4) This Python script generates a Tkinter window, populating it with
information from the CSA.
5) Control will not pass back to the CSA until the Tkinter window is
closed. Because of this, none of the CSA's tools can be used until the
Tkinter window is closed.

Scenario B:
1) I start out inside the CSA.
2) I initiate a script in the CSA's scripting language.
3) This script calls an external Python script in a new thread.
4) This Python script generates a Tkinter window, populating it with
information from the CSA.
5) Control returns to the CSA while the Tkinter window is populating
itself. The CSA's tools can be used while the Tkinter window remains
open displaying its information.

My users want scenario B to occur. This way they can refer to the
Tkinter window's info and make changes to their plan based on this
info. However! Once they make their changes they will want to rerun
the same Python script. This would then result in TWO Tkinter windows
being open, one displaying the old info, the new one with the
post-changes info. This is not acceptable.

So, how do I:
1) Check for the existence of an already open window from a previous
running of the script?
2) If such a window exists, how do I close it from the new script
execution? And, then, of course generate a new instance of the
information window.

I need to be able to identify the existence of such a window without
causing anything to happen to the CSA's normally open windows. And
then close the particular window I need closed -- IF it is even open.
I feel the solution must be in Tkinter's access to the X Window
system, but nothing in the documentation is *clicking* with me yet.

Thanks!

-- 
boB

From alan.gauld at btinternet.com  Mon Apr 20 09:10:38 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Apr 2015 08:10:38 +0100
Subject: [Tutor] How to close a Tkinter window from a different thread?
In-Reply-To: <CANDiX9LVDvbYoaVSzvLJeFpjqJrKf=Yt79nNnVtKXHbZ6ooKZA@mail.gmail.com>
References: <CANDiX9LVDvbYoaVSzvLJeFpjqJrKf=Yt79nNnVtKXHbZ6ooKZA@mail.gmail.com>
Message-ID: <mh28pc$cq5$1@ger.gmane.org>

On 20/04/15 04:34, boB Stepp wrote:

> So, how do I:
> 1) Check for the existence of an already open window from a previous
> running of the script?
> 2) If such a window exists, how do I close it from the new script
> execution? And, then, of course generate a new instance of the
> information window.

I would suggest forgetting about windows and think about
the processes that create them. Use the OS tools (via
the os module) to see if the first process is still running.
If so kill the process - which will in turn kill the window.

You can find the process based on its name or based on
its PID which you could store in a file somewhere
(like in /tmp?)

> I feel the solution must be in Tkinter's access to the X Window
> system, but nothing in the documentation is *clicking* with me yet.

Trying to manipulate GUIs via the windowing system should always
be a last resort, it is very hard to get right.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From cybervigilante at gmail.com  Mon Apr 20 05:49:27 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sun, 19 Apr 2015 20:49:27 -0700
Subject: [Tutor] sample dictionairies
Message-ID: <CALRAYNVrMGrJOFMhv3zHasiAqSr8GsFMgjn4WXZ5r1edxUhkPQ@mail.gmail.com>

For randomly generating data which look like addresses, I use:

> http://www.generatedata.com/
>
> While it has 'export to programming language' as a feature, Python isn't
> one of the supported languages.  Which is fine.  It can export into comma
> separated values, and writing a Python program to construct a dictionary
> from comma separated values is easy.
>
> Laura
>

That's a great source, and I can generate dictionaries using the other
advice. If you don't request comma delimited, each record per line has   |
as a field delimiter, so making big dicts was easy. Naturally, I tried
emailing one of the addresses - aliquam at Nunc.org - but it appears to be
dead ;')

Come to think of it, since I used  |  as a delimiter, what happens if you
generate a CSV file from data that already has commas in the text?

-- 
Jim

From niyniyniym at gmail.com  Mon Apr 20 02:36:59 2015
From: niyniyniym at gmail.com (niy mor)
Date: Sun, 19 Apr 2015 20:36:59 -0400
Subject: [Tutor] Life Grid Implementation
Message-ID: <CAJjemjmfmbbxMgHF_8w2pVEkFM55RMp24_3RSXnb8CgGGm9Hsg@mail.gmail.com>

Is my code completing the assignment??? I need some *guidance* on
completing my assignment.

My Assignment:
A sparse life grid is used to store and represent the area in the game of
Life that contains organisms. The grid contains a rectangular grouping of
cells divided into an infinite number of rows and columns. The individual
cells, which can be alive or dead, are referenced by integer row and column
indices. The operations defined for the ADT are as follows:
? SparseLifeGrid() Creates a new infinite-sized game grid with all cells
initially dead.
 ? minRange() Returns a 2-tuple (minrow, mincol) that contains the minimum
row index and the minimum column index that is currently occupied by a live
cell. The tuple (0, 0) is returned if there are no live cells.
 ? maxRange() Returns a 2-tuple (maxrow, maxcol) that contains the maximum
row index and the maximum column index that is currently occupied by a live
cell. The tuple (0, 0) is returned if there are no live cells.
 ? clearCell(row, col) Clears the individual cell (row, col) and sets it to
dead. If the cell is already dead, no action is taken.
 ? setCell(row, col) Sets the indicated cell (row, col) to be alive. If the
cell is already alive, no action is taken.
 ? isLiveCell(row, col) Returns a Boolean value indicating if the given
cell (row, col) contains a live organism.
? numLiveNeighbors(row, col) Returns the number of live neighbors for the
given cell (row, col). The neighbors of a cell include all of the cells
immediately surrounding it in all directions.

My Attempt Code:
class SparseLifeGrid :

    Cell = ["row", "col"]

    def __init__( self ):
        self._rowList = []
        self._colList = []
        self._cellSet = set()

    def _binarySearch( self, target ) :
        low = 0
        high = len(self._cellSet - 1)
        while low <= high :
            mid = (high + low) // 2
        if theList[mid] == target :
            return (True, mid)
        elif target < theList[mid] :
            high = mid - 1
        else :
                low = mid + 1

        return (False, low)


    def minRange( self ):
        return (sorted(self._rowList)[0], sorted(self._rowList)[0])

    def maxRange( self ):
        return (sorted(self._rowList, reverse = True)[0],\
                sorted(self._colList, reverse = True)[0])


     # Clears the individual cell (row, col) and sets it to dead. If the
cell is
     # already dead, no action is taken
    def clearCell( self, row, col ):
        for item in self :
            if item == Cell(row, col) :
                self.remove(item)

    def setCell( self, row, col ):
        LIVE_CELL = 1
        Cell[row, col] = LIVE_CELL

    def isLiveCell( self, row, col):
        return Cell(row,col) in self

    def numLiveNeighbors( self, row, col ):
        surround = 0
        if self.isLiveCell(row + 1, col) :
            surround += 1
        if self.isLiveCell(row - 1, col) :
            surround += 1
        if self.isLiveCell(row, col + 1) :
            surround += 1
        if self.isLiveCell(row, col - 1) :
            surround += 1

From alan.gauld at btinternet.com  Mon Apr 20 09:26:35 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Apr 2015 08:26:35 +0100
Subject: [Tutor] sample dictionairies
In-Reply-To: <CALRAYNVrMGrJOFMhv3zHasiAqSr8GsFMgjn4WXZ5r1edxUhkPQ@mail.gmail.com>
References: <CALRAYNVrMGrJOFMhv3zHasiAqSr8GsFMgjn4WXZ5r1edxUhkPQ@mail.gmail.com>
Message-ID: <mh29n9$p1d$1@ger.gmane.org>

On 20/04/15 04:49, Jim Mooney wrote:

> Come to think of it, since I used  |  as a delimiter, what happens if you
> generate a CSV file from data that already has commas in the text?

The CSV format covers that eventuality: You put quotes around the
item with the comma.
And if there are already quotes?
And if there are newlines inside one of the fields?

Its all covered in the CSV spec.

Which is why you should use the csv module to work with csv files,
it knows how to deal with these various exceptional cases.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From ben+python at benfinney.id.au  Mon Apr 20 09:30:39 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Mon, 20 Apr 2015 17:30:39 +1000
Subject: [Tutor] Life Grid Implementation
References: <CAJjemjmfmbbxMgHF_8w2pVEkFM55RMp24_3RSXnb8CgGGm9Hsg@mail.gmail.com>
Message-ID: <85r3rfntnk.fsf@benfinney.id.au>

niy mor <niyniyniym at gmail.com> writes:

> Is my code completing the assignment???

Does it meet the requirements when you (and other people) run the code?

> I need some *guidance* on completing my assignment.

Can you be specific about what you don't understand?

If you don't understand the requirements, that is best discussed with
your course supervisor, not us.

-- 
 \           ?Kissing a smoker is like licking an ashtray.? ?anonymous |
  `\                                                                   |
_o__)                                                                  |
Ben Finney


From alan.gauld at btinternet.com  Mon Apr 20 09:39:50 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Apr 2015 08:39:50 +0100
Subject: [Tutor] Life Grid Implementation
In-Reply-To: <CAJjemjmfmbbxMgHF_8w2pVEkFM55RMp24_3RSXnb8CgGGm9Hsg@mail.gmail.com>
References: <CAJjemjmfmbbxMgHF_8w2pVEkFM55RMp24_3RSXnb8CgGGm9Hsg@mail.gmail.com>
Message-ID: <mh2ag4$7uc$1@ger.gmane.org>

On 20/04/15 01:36, niy mor wrote:
> Is my code completing the assignment???

No.

> I need some *guidance* on
> completing my assignment.

Try running your code.
Then fix the errors.
If you can't fix them come back to us and ask for help,
including the error message and a description of what
happened and what you expected.

> My Attempt Code:
> class SparseLifeGrid :
>
>      Cell = ["row", "col"]

What is this for?

>      def __init__( self ):
>          self._rowList = []
>          self._colList = []
>          self._cellSet = set()
>
>      def _binarySearch( self, target ) :
>          low = 0
>          high = len(self._cellSet - 1)
>          while low <= high :
>              mid = (high + low) // 2
>          if theList[mid] == target :
>              return (True, mid)
>          elif target < theList[mid] :
>              high = mid - 1
>          else :
>                  low = mid + 1
>
>          return (False, low)

This just tells you which half the item is in.
Is that what you wanted?

>      def minRange( self ):
>          return (sorted(self._rowList)[0], sorted(self._rowList)[0])

This returns the same value twice.

>      def maxRange( self ):
>          return (sorted(self._rowList, reverse = True)[0],\
>                  sorted(self._colList, reverse = True)[0])

You don;t need the line continuation character (/) if you are inside parens.

def f():
    return (expression1,
            expression2)

>       # Clears the individual cell (row, col) and sets it to dead. If the
> cell is
>       # already dead, no action is taken
>      def clearCell( self, row, col ):
>          for item in self :
>              if item == Cell(row, col) :
>                  self.remove(item)

How do you expect to iterate over self? self is your class instance
but it has nothing to iterate over?

>      def setCell( self, row, col ):
>          LIVE_CELL = 1
>          Cell[row, col] = LIVE_CELL

Here you create a new Cell instance then try to assign a value to it, 
then throw it away. I'm pretty sure thats not what you want.

>      def isLiveCell( self, row, col):
>          return Cell(row,col) in self

Again how are you testing 'in' self. There is nothing in
your class to support that.

>
>      def numLiveNeighbors( self, row, col ):
>          surround = 0
>          if self.isLiveCell(row + 1, col) :
>              surround += 1
>          if self.isLiveCell(row - 1, col) :
>              surround += 1
>          if self.isLiveCell(row, col + 1) :
>              surround += 1
>          if self.isLiveCell(row, col - 1) :
>              surround += 1

How many neighbours does a cell have in a Life grid?
Is it only 4?


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From breamoreboy at yahoo.co.uk  Mon Apr 20 09:55:21 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Mon, 20 Apr 2015 08:55:21 +0100
Subject: [Tutor] sample dictionairies
In-Reply-To: <CALRAYNVrMGrJOFMhv3zHasiAqSr8GsFMgjn4WXZ5r1edxUhkPQ@mail.gmail.com>
References: <CALRAYNVrMGrJOFMhv3zHasiAqSr8GsFMgjn4WXZ5r1edxUhkPQ@mail.gmail.com>
Message-ID: <mh2bda$mlr$1@ger.gmane.org>

On 20/04/2015 04:49, Jim Mooney wrote:
> For randomly generating data which look like addresses, I use:
>
>> http://www.generatedata.com/
>>
>> While it has 'export to programming language' as a feature, Python isn't
>> one of the supported languages.  Which is fine.  It can export into comma
>> separated values, and writing a Python program to construct a dictionary
>> from comma separated values is easy.
>>
>> Laura
>>
>
> That's a great source, and I can generate dictionaries using the other
> advice. If you don't request comma delimited, each record per line has   |
> as a field delimiter, so making big dicts was easy. Naturally, I tried
> emailing one of the addresses - aliquam at Nunc.org - but it appears to be
> dead ;')
>
> Come to think of it, since I used  |  as a delimiter, what happens if you
> generate a CSV file from data that already has commas in the text?
>

For those who don't know you can use any character as the delimiter and 
any character as the quote, see 
https://docs.python.org/3/library/csv.html#csv.reader

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From robertvstepp at gmail.com  Mon Apr 20 14:45:50 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 20 Apr 2015 07:45:50 -0500
Subject: [Tutor] How to close a Tkinter window from a different thread?
In-Reply-To: <mh28pc$cq5$1@ger.gmane.org>
References: <CANDiX9LVDvbYoaVSzvLJeFpjqJrKf=Yt79nNnVtKXHbZ6ooKZA@mail.gmail.com>
 <mh28pc$cq5$1@ger.gmane.org>
Message-ID: <CANDiX9+EZMATv7w1nn_xqxMux=macoVCLL=m7RXfKVDN_afLpA@mail.gmail.com>

On Mon, Apr 20, 2015 at 2:10 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 20/04/15 04:34, boB Stepp wrote:
>
>> So, how do I:
>> 1) Check for the existence of an already open window from a previous
>> running of the script?
>> 2) If such a window exists, how do I close it from the new script
>> execution? And, then, of course generate a new instance of the
>> information window.
>
>
> I would suggest forgetting about windows and think about
> the processes that create them. Use the OS tools (via
> the os module) to see if the first process is still running.
> If so kill the process - which will in turn kill the window.

I started poking around a little in this area in my books, but did not
know if this was the way to go or not. I was still hung up on how to
identify the correct process...

> You can find the process based on its name or based on
> its PID which you could store in a file somewhere
> (like in /tmp?)

I was thinking in these terms from a Tkinter window id perspective,
but storing the PID while the original window is known to be open
looks like the way to go. Thanks, Alan! I may have more questions on
this later as I have not explicitly worked with this via Python. I've
only killed processes via the command line before.

>> I feel the solution must be in Tkinter's access to the X Window
>> system, but nothing in the documentation is *clicking* with me yet.
>
>
> Trying to manipulate GUIs via the windowing system should always
> be a last resort, it is very hard to get right.

If I am learning nothing else from my exploration of GUI programming,
this is becoming ever more evident!

-- 
boB

From cybervigilante at gmail.com  Mon Apr 20 09:44:12 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Mon, 20 Apr 2015 00:44:12 -0700
Subject: [Tutor] bin to dec conversion puzzlement
Message-ID: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>

I can't seem to get my head around this 'simple' book example of
binary-to-decimal conversion, which goes from left to right:

B = '11011101'
I = 0
while B:
    I = I * 2 + int(B[0])
    B = B[1:]

print(I)
>>> 221

My thought was to go from right to left, multiplying digits by successive
powers of two, and adding, like so:

B = '11011101'
sum = 0

for exp, num in enumerate(reversed(B)):
    sum += int(num) * 2**exp

print(sum)
>> 221

Both methods work but I just can't see how the first one does. Am I missing
something obvious here?

-- 
Jim

From cybervigilante at gmail.com  Mon Apr 20 09:50:33 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Mon, 20 Apr 2015 00:50:33 -0700
Subject: [Tutor] sample dictionairies
In-Reply-To: <mh29n9$p1d$1@ger.gmane.org>
References: <CALRAYNVrMGrJOFMhv3zHasiAqSr8GsFMgjn4WXZ5r1edxUhkPQ@mail.gmail.com>
 <mh29n9$p1d$1@ger.gmane.org>
Message-ID: <CALRAYNVyzjSNtpa0=jRnL6Omcu0ifznqd8s_o9GiXQ5sJC3efA@mail.gmail.com>

> Which is why you should use the csv module to work with csv files,
> it knows how to deal with these various exceptional cases.
> --
> Alan G
>

I should have known to simply try importing csv.
Must-remember-batteries-included ;')

-- 
Jim

From lac at openend.se  Mon Apr 20 10:49:41 2015
From: lac at openend.se (Laura Creighton)
Date: Mon, 20 Apr 2015 10:49:41 +0200
Subject: [Tutor] OT: Is there a good book that covers the
	history/evolution of software? [Inspired by the thread: lists,
	name semantics]
In-Reply-To: Message from boB Stepp <robertvstepp@gmail.com> of "Sun,
 19 Apr 2015 20:03:02 -0500."
 <CANDiX9LjyeZMxz_pLJWU11924u6go6yGL-GbCS10RUs=BVY3Wg@mail.gmail.com>
References: <CANDiX9LjyeZMxz_pLJWU11924u6go6yGL-GbCS10RUs=BVY3Wg@mail.gmail.com>
Message-ID: <201504200849.t3K8ngkK008889@fido.openend.se>

Newman, W., Sproull, R. (1979), Principles of Interactive Computer Graphics, Mcgraw-Hill College, ISBN 0-07-046338-7

is a very good read.  It is understandably dated, but then it was
history that you were looking for.  And the book has 2 parts -- a
history of the computer architectures we had (in 1979) and then
the part on how to make grapical programs on them.

Laura


From lac at openend.se  Mon Apr 20 11:40:33 2015
From: lac at openend.se (Laura Creighton)
Date: Mon, 20 Apr 2015 11:40:33 +0200
Subject: [Tutor] How to close a Tkinter window from a different thread?
In-Reply-To: Message from Alan Gauld <alan.gauld@btinternet.com>
 of "Mon, 20 Apr 2015 08:10:38 +0100." <mh28pc$cq5$1@ger.gmane.org>
References: <CANDiX9LVDvbYoaVSzvLJeFpjqJrKf=Yt79nNnVtKXHbZ6ooKZA@mail.gmail.com><mh28pc$cq5$1@ger.gmane.org>
Message-ID: <201504200940.t3K9eXLM010578@fido.openend.se>

In a message of Mon, 20 Apr 2015 08:10:38 +0100, Alan Gauld writes:

>Trying to manipulate GUIs via the windowing system should always
>be a last resort, it is very hard to get right.

And the hardness increases exponentially if you want to be portable
across different operating systems.

Laura


From lac at openend.se  Mon Apr 20 11:45:16 2015
From: lac at openend.se (Laura Creighton)
Date: Mon, 20 Apr 2015 11:45:16 +0200
Subject: [Tutor] sample dictionairies
In-Reply-To: Message from Jim Mooney <cybervigilante@gmail.com> of "Sun,
 19 Apr 2015 20:49:27 -0700."
 <CALRAYNVrMGrJOFMhv3zHasiAqSr8GsFMgjn4WXZ5r1edxUhkPQ@mail.gmail.com>
References: <CALRAYNVrMGrJOFMhv3zHasiAqSr8GsFMgjn4WXZ5r1edxUhkPQ@mail.gmail.com>
Message-ID: <201504200945.t3K9jG4p010702@fido.openend.se>

In a message of Sun, 19 Apr 2015 20:49:27 -0700, Jim Mooney writes:
>Come to think of it, since I used  |  as a delimiter, what happens if you
>generate a CSV file from data that already has commas in the text?
>
>-- 
>Jim

In Sweden, and lots of other places, we do numbers differently.
This is One thousand dollars and 43 cents. 1.000,43

Lots of the time you write that as 1000,43  same as in English you
get 1000.43 and 1,000.43.

So we tend to use comma separated values around here that are really
semi-colon separated values.  But I do not know how widespread that usage
is.

Laura


From mchirmure at gmail.com  Mon Apr 20 10:54:46 2015
From: mchirmure at gmail.com (Mahesh Chiramure)
Date: Mon, 20 Apr 2015 14:24:46 +0530
Subject: [Tutor] Please Help to build an addon for Anki
In-Reply-To: <CAN=W7ZwRQi_pTZ65WZ_7b_mnZZgUsiJLTg5z9ZodK5m=skewOg@mail.gmail.com>
References: <CAN=W7ZwRQi_pTZ65WZ_7b_mnZZgUsiJLTg5z9ZodK5m=skewOg@mail.gmail.com>
Message-ID: <CAN=W7Zy4dyMvvntUoHyKxHCTO4T91Ye0jy3BjfWMmZf1SfbSAw@mail.gmail.com>

Hi

I liked the addon "Picture-flasher" written for anki very much
and I was wondering if the same thing could be done with mp3 and/or
flac files. Means I am looking for an addon that chooses a random mp3
and/or flac file from a directory provided by me (to the addon as we
have to provide in "Picture-flasher") and plays it on successful
reviewing of a certain number of cards (as does the addon
"Picture-flasher"). As a music lover, I feel that this addon can
motivate a whole lot of music lovers out there to pay a visit to Anki
on their PC and review to listen to their favorite mp3 and/or flac
files as a reward.

I am not a programmer yet, please guide.

Hoping for a quick response.

Mahesh Chirmure
-------------- next part --------------
# -*- coding: utf-8 -*-
# Picture-Flasher (a plugin for Anki)
# Authors:
#   Emanuel Rylke, ema-fox at web.de
#   D_Malik, malik6174 at gmail.com
# Version 2
# License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html

"""
A simple plugin that flashes pictures on-screen to reinforce reviews.

Before using:
- Get pictures from someplace. I downloaded pictures off reddit using the script at https://github.com/dpbrown/RedditImageGrab
- Change all lines (in the plugin source) marked with "CHANGEME" according to your preferences.

For more details, see the post at For more details, see the post at http://lesswrong.com/r/discussion/lw/frc/two_anki_plugins_to_reinforce_reviewing/
"""

from anki.hooks import addHook
from aqt import mw
from random import random, choice
from aqt.qt import QSplashScreen, QPixmap, QTimer
from os import listdir

#------ begin configuration ------#
pictureDirectory = "E://Family stuff//22 Feb//Personal//College//A J//" #CHANGEME to the directory where you're storing your pictures. NB: This MUST end with a trailing slash e.g. D://Family stuff//19 Jan//Imgs//Wallys//, D://Family stuff//22 Feb//Imgs//Windows 7//.

flashTime = 3000 #CHANGEME to change how long pictures stay on the screen. The number is time in milliseconds.

#flashPosition = [20, 1050] #CHANGEME if you want the picture to be shown at a specific location. The numbers are x- and y-coordinates.

    #CHANGEME: The next lines are a python dictionary associating deck names with probabilities of pictures being shown.
    #Eg, when using the deck "brainscience", you will get a picture after 30% of cards. When using a deck without a listed name, "other" is used.
    #Change this according to your decks. Decks with shorter, easier cards need lower probabilities.
deckPicsProbabilities = {
    "rocketsurgery"    :   0.3,
    "brainscience"     :   0.5,
    "other"            :   0.1,
    }
#------- end configuration -------#

pics = listdir(pictureDirectory)

def showPics():
    if mw.col.decks.current()['name'] in deckPicsProbabilities:
        picsProbability = deckPicsProbabilities[mw.col.decks.current()['name']]
    else:
        picsProbability = deckPicsProbabilities["other"]
        
    if random() < picsProbability:
        mw.splash = QSplashScreen(QPixmap(pictureDirectory + choice(pics)))
        try:
            mw.splash.move(flashPosition[0], flashPosition[1])
        except NameError:
            pass
        mw.splash.show()
        QTimer.singleShot(flashTime, mw.splash.close)

addHook("showQuestion", showPics)

From niyanaxx95 at gmail.com  Mon Apr 20 14:59:20 2015
From: niyanaxx95 at gmail.com (niyana morgan)
Date: Mon, 20 Apr 2015 08:59:20 -0400
Subject: [Tutor] Life Grid Implementation
In-Reply-To: <85r3rfntnk.fsf@benfinney.id.au>
References: <CAJjemjmfmbbxMgHF_8w2pVEkFM55RMp24_3RSXnb8CgGGm9Hsg@mail.gmail.com>
 <85r3rfntnk.fsf@benfinney.id.au>
Message-ID: <CACG__YhZniJiGbUAphJy2ggTngm0ofAr-JoObzFA-tYGsqF4pQ@mail.gmail.com>

I don't understand how to do this. I attempted with my code and hoped a
tutor could help me with this
On Apr 20, 2015 3:31 AM, "Ben Finney" <ben+python at benfinney.id.au> wrote:

> niy mor <niyniyniym at gmail.com> writes:
>
> > Is my code completing the assignment???
>
> Does it meet the requirements when you (and other people) run the code?
>
> > I need some *guidance* on completing my assignment.
>
> Can you be specific about what you don't understand?
>
> If you don't understand the requirements, that is best discussed with
> your course supervisor, not us.
>
> --
>  \           ?Kissing a smoker is like licking an ashtray.? ?anonymous |
>   `\                                                                   |
> _o__)                                                                  |
> Ben Finney
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From marc.tompkins at gmail.com  Mon Apr 20 17:21:11 2015
From: marc.tompkins at gmail.com (Marc Tompkins)
Date: Mon, 20 Apr 2015 08:21:11 -0700
Subject: [Tutor] bin to dec conversion puzzlement
In-Reply-To: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
References: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
Message-ID: <CAKK8jXZ_nj9=aXuBBU-iUUO0oipBkH7o9vm9HkQ-dn3--3mzPA@mail.gmail.com>

On Apr 20, 2015 6:56 AM, "Jim Mooney" <cybervigilante at gmail.com> wrote:
>
> I can't seem to get my head around this 'simple' book example of
> binary-to-decimal conversion, which goes from left to right:
>
> B = '11011101'
> I = 0
> while B:
>     I = I * 2 + int(B[0])
>     B = B[1:]
>
> print(I)
> >>> 221
>
> My thought was to go from right to left, multiplying digits by successive
> powers of two, and adding, like so:
>
> B = '11011101'
> sum = 0
>
> for exp, num in enumerate(reversed(B)):
>     sum += int(num) * 2**exp
>
> print(sum)
> >> 221
>
> Both methods work but I just can't see how the first one does. Am I
missing
> something obvious

Start from 0.
As long as there are any digits left,
a) Multiply by 2, add the leftmost digit.
b) Chop off the leftmost digit.
Lather, rinse, repeat.

It _does_ seem counterintuitive to do it from the left, but it's actually
quite simple.

From oscar.j.benjamin at gmail.com  Mon Apr 20 17:24:57 2015
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Mon, 20 Apr 2015 16:24:57 +0100
Subject: [Tutor] bin to dec conversion puzzlement
In-Reply-To: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
References: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
Message-ID: <CAHVvXxQAvA5dh-AZbosbPJPHEX=iwaVoHo7Gs6rbW0wV1oAOaQ@mail.gmail.com>

On 20 April 2015 at 08:44, Jim Mooney <cybervigilante at gmail.com> wrote:
> I can't seem to get my head around this 'simple' book example of
> binary-to-decimal conversion, which goes from left to right:
>
> B = '11011101'
> I = 0
> while B:
>     I = I * 2 + int(B[0])
>     B = B[1:]


Follow through the loop and see what happens. To begin I is zero and B
is the full string. Consider B_orig to be the original string. After
the first iteration we have that
     I = B[0]   and   B = B_orig[1:]
then
     I = 2*B[0] + B[1]  and B = B_orig[2:]
then
    I = 2*(2*B[0] + B[1]) + B[2]  = 4*B[0] + 2*B[1] + B[2]
then
    I = 8*B[0] + 4*B[1] + 2*B[2] + B[3]
and eventually
    I = 128*B[0] + 64*B[1] + ... + 2*B[6] + B[7]
which is the desired result.


Oscar

From akleider at sonic.net  Mon Apr 20 17:24:42 2015
From: akleider at sonic.net (Alex Kleider)
Date: Mon, 20 Apr 2015 08:24:42 -0700
Subject: [Tutor] introspection
Message-ID: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>

Does python provide the introspective ability to retrieve the name to 
which an object is bound?

For example:
$ python3
Python 3.4.0 (default, Apr 11 2014, 13:05:18)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 69
>>> print("Identifier <{}> is bound to {}.".format(a.__name__, a))
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__name__'






From joel.goldstick at gmail.com  Mon Apr 20 18:15:44 2015
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Mon, 20 Apr 2015 12:15:44 -0400
Subject: [Tutor] introspection
In-Reply-To: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
Message-ID: <CAPM-O+xi2dGDsoZ8zVPZeY7vNbDM3=_-zdDqN1YJW-rfKbkUiQ@mail.gmail.com>

On Mon, Apr 20, 2015 at 11:24 AM, Alex Kleider <akleider at sonic.net> wrote:
> Does python provide the introspective ability to retrieve the name to which
> an object is bound?
>
> For example:
> $ python3
> Python 3.4.0 (default, Apr 11 2014, 13:05:18)
> [GCC 4.8.2] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>>>>
>>>> a = 69
>>>> print("Identifier <{}> is bound to {}.".format(a.__name__, a))
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> AttributeError: 'int' object has no attribute '__name__'
>
>
An object can be bound to multiple names.  Within a namespace you can
use locals to see names, then compare various names like so:
>
>>> a = 3
>>> b = 6
>>> c = a
>>> locals()
{'a': 3, 'c': 3, 'b': 6, '__builtins__': <module '__builtin__'
(built-in)>, '__package__': None, '__name__': '__main__', '__doc__':
None}
>>> a is b
False
>>> a is c
True
>>>

>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Joel Goldstick
http://joelgoldstick.com

From alan.gauld at btinternet.com  Mon Apr 20 18:16:27 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Apr 2015 17:16:27 +0100
Subject: [Tutor] Life Grid Implementation
In-Reply-To: <CACG__YhZniJiGbUAphJy2ggTngm0ofAr-JoObzFA-tYGsqF4pQ@mail.gmail.com>
References: <CAJjemjmfmbbxMgHF_8w2pVEkFM55RMp24_3RSXnb8CgGGm9Hsg@mail.gmail.com>
 <85r3rfntnk.fsf@benfinney.id.au>
 <CACG__YhZniJiGbUAphJy2ggTngm0ofAr-JoObzFA-tYGsqF4pQ@mail.gmail.com>
Message-ID: <mh38op$e61$1@ger.gmane.org>

On 20/04/15 13:59, niyana morgan wrote:
> I don't understand how to do this. I attempted with my code and hoped a
> tutor could help me with this

Always write code that runs. Then fix the mistakes as they
happen. That way you only have a few lines of code to look
at. Your code is far too big and intertwined to be able
to debug easily.

Look at your specification:
? SparseLifeGrid() Creates a new infinite-sized game grid
    with all cells initially dead.
...
  ? clearCell(row, col) Clears the individual cell (row, col)
    and sets it to dead. If the cell is already dead, no action
    is taken.
  ? setCell(row, col) Sets the indicated cell (row, col)
    to be alive. If the cell is already alive, no action is taken.
....

I suggest you start over with a class definition and an init().
See if you can create an instance and if it has the
fields you expect. Thats your first API bullet done.

Once you can do that create the methods needed to populate
it with data (setCell()) and clear a cell(clearCell()).
Nothing else, just those two methods. Get them working.
Now you have three parts of your assignment done.

Only when you can do those things correctly attempt one of the remaining 
API methods - maybe the isLiveCell() method.

Then try minRange and maxRange after that.

Finally you can try numLiveNeighbours confident that the
rest of the class works.

Always run the code. Every time you complete a method
your code should work. If you write your tests as code
in a function, that function should always work even
after you complete a new stage. If anything that used
to work stops working, go back and fix it before trying
anything new. The code you changed will still be fresh
in your mind.

If you really get stuck come back here and ask.
Always copy any error messages in full.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Mon Apr 20 18:21:51 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Apr 2015 17:21:51 +0100
Subject: [Tutor] bin to dec conversion puzzlement
In-Reply-To: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
References: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
Message-ID: <mh392t$e61$2@ger.gmane.org>

On 20/04/15 08:44, Jim Mooney wrote:
> I can't seem to get my head around this 'simple' book example of
> binary-to-decimal conversion, which goes from left to right:
>
> B = '11011101'
> I = 0
> while B:
>      I = I * 2 + int(B[0])
>      B = B[1:]
...
> Both methods work but I just can't see how the first one does.

The key is that the result gets multiplied by 2 each time
so for an N bit number the leftmost digit winds up being
effectively 2**N, which is what you want.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Mon Apr 20 18:27:25 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Apr 2015 17:27:25 +0100
Subject: [Tutor] Please Help to build an addon for Anki
In-Reply-To: <CAN=W7Zy4dyMvvntUoHyKxHCTO4T91Ye0jy3BjfWMmZf1SfbSAw@mail.gmail.com>
References: <CAN=W7ZwRQi_pTZ65WZ_7b_mnZZgUsiJLTg5z9ZodK5m=skewOg@mail.gmail.com>
 <CAN=W7Zy4dyMvvntUoHyKxHCTO4T91Ye0jy3BjfWMmZf1SfbSAw@mail.gmail.com>
Message-ID: <mh39db$pee$1@ger.gmane.org>

On 20/04/15 09:54, Mahesh Chiramure wrote:

> I liked the addon "Picture-flasher" written for anki very much
> and I was wondering if the same thing could be done with mp3 and/or
> flac files.

Probably, but I (and probably most of the list) have no idea what anki 
is or what the addon does. This is a list for learning Python and its 
standard library. You could try asking on the general Python 
mailinglist/newsgroup where you might find someone familiar with it.

If you do try that you sould try explaining what anki is,
and what the addon does. ie how it 'adds on'.

Better still is if you can find an anki forum, since they will 
understand anki, addons and probably be familiar with the PictureFlasher 
one you describe.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From akleider at sonic.net  Mon Apr 20 18:55:41 2015
From: akleider at sonic.net (Alex Kleider)
Date: Mon, 20 Apr 2015 09:55:41 -0700
Subject: [Tutor] introspection
In-Reply-To: <CAPM-O+xi2dGDsoZ8zVPZeY7vNbDM3=_-zdDqN1YJW-rfKbkUiQ@mail.gmail.com>
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
 <CAPM-O+xi2dGDsoZ8zVPZeY7vNbDM3=_-zdDqN1YJW-rfKbkUiQ@mail.gmail.com>
Message-ID: <53b5d70a1b929de9cad143f11802c795@sonic.net>

On 2015-04-20 09:15, Joel Goldstick wrote:
> On Mon, Apr 20, 2015 at 11:24 AM, Alex Kleider <akleider at sonic.net> 
> wrote:
>> Does python provide the introspective ability to retrieve the name to 
>> which
>> an object is bound?
>> 
>> For example:
>> $ python3
>> Python 3.4.0 (default, Apr 11 2014, 13:05:18)
>> [GCC 4.8.2] on linux
>> Type "help", "copyright", "credits" or "license" for more information.
>>>>> 
>>>>> a = 69
>>>>> print("Identifier <{}> is bound to {}.".format(a.__name__, a))
>> 
>> Traceback (most recent call last):
>>   File "<stdin>", line 1, in <module>
>> AttributeError: 'int' object has no attribute '__name__'
>> 
>> 
> An object can be bound to multiple names.  Within a namespace you can
> use locals to see names, then compare various names like so:
>> 
>>>> a = 3
>>>> b = 6
>>>> c = a
>>>> locals()
> {'a': 3, 'c': 3, 'b': 6, '__builtins__': <module '__builtin__'
> (built-in)>, '__package__': None, '__name__': '__main__', '__doc__':
> None}
>>>> a is b
> False
>>>> a is c
> True

Showing my desired use case might make my question more understandable:
def debug(var_name):
     if args["--debug"]:
         print("Identifier <{}> is bound to: {}"
             .format(var_name.__name__, repr(var_name)))
I don't think the built in locals() can help me.
Thanks all the same.
Alex



From akleider at sonic.net  Mon Apr 20 18:58:37 2015
From: akleider at sonic.net (Alex Kleider)
Date: Mon, 20 Apr 2015 09:58:37 -0700
Subject: [Tutor] bin to dec conversion puzzlement
In-Reply-To: <mh392t$e61$2@ger.gmane.org>
References: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
 <mh392t$e61$2@ger.gmane.org>
Message-ID: <d920fdfc32e719d27657e2fa504939ad@sonic.net>

On 2015-04-20 09:21, Alan Gauld wrote:
> On 20/04/15 08:44, Jim Mooney wrote:
>> I can't seem to get my head around this 'simple' book example of
>> binary-to-decimal conversion, which goes from left to right:
>> 
>> B = '11011101'
>> I = 0
>> while B:
>>      I = I * 2 + int(B[0])
>>      B = B[1:]
> ...
>> Both methods work but I just can't see how the first one does.
> 
> The key is that the result gets multiplied by 2 each time
> so for an N bit number the leftmost digit winds up being
> effectively 2**N, which is what you want.

Shouldn't that be 2**(N-1)?

From alan.gauld at btinternet.com  Mon Apr 20 19:14:33 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Apr 2015 18:14:33 +0100
Subject: [Tutor] bin to dec conversion puzzlement
In-Reply-To: <d920fdfc32e719d27657e2fa504939ad@sonic.net>
References: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
 <mh392t$e61$2@ger.gmane.org> <d920fdfc32e719d27657e2fa504939ad@sonic.net>
Message-ID: <mh3c5n$9qs$1@ger.gmane.org>

On 20/04/15 17:58, Alex Kleider wrote:

>> The key is that the result gets multiplied by 2 each time
>> so for an N bit number the leftmost digit winds up being
>> effectively 2**N, which is what you want.
>
> Shouldn't that be 2**(N-1)?

Yes, sorry.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From eryksun at gmail.com  Mon Apr 20 19:14:27 2015
From: eryksun at gmail.com (eryksun)
Date: Mon, 20 Apr 2015 12:14:27 -0500
Subject: [Tutor] bin to dec conversion puzzlement
In-Reply-To: <mh392t$e61$2@ger.gmane.org>
References: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
 <mh392t$e61$2@ger.gmane.org>
Message-ID: <CACL+1as5-nw=CYoTkuScaNH_ENaFZnj3ZCepbYa9EUNrZxeQxQ@mail.gmail.com>

On Mon, Apr 20, 2015 at 11:21 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>>
>> B = '11011101'
>> I = 0
>> while B:
>>      I = I * 2 + int(B[0])
>>      B = B[1:]
>
>> Both methods work but I just can't see how the first one does.
>
> The key is that the result gets multiplied by 2 each time
> so for an N bit number the leftmost digit winds up being
> effectively 2**N, which is what you want.

The loop iterates N times, so the leftmost digit is multiplied by 2 a
total of N - 1 times, i.e. B[0] * 2 ** (N - 1).

Another way to see this is that multiplying by 2 is a bitwise left
shift. Thus you can replace the multiplication and addition with
bitwise operations as follows:

    B = '11011101'
    I = 0
    while B:
        I = (I << 1) | int(B[0], 2)
        B = B[1:]
   assert I == 221

Shifting the values in like this may be more intuitively obvious.

From steve at pearwood.info  Mon Apr 20 19:15:17 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Tue, 21 Apr 2015 03:15:17 +1000
Subject: [Tutor] introspection
In-Reply-To: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
Message-ID: <20150420171516.GG5663@ando.pearwood.info>

On Mon, Apr 20, 2015 at 08:24:42AM -0700, Alex Kleider wrote:
> Does python provide the introspective ability to retrieve the name to 
> which an object is bound?

Short answer: no.

Slightly longer answer: it *may* be possible if you dig deep into the 
debugger API that you might find something which does what you want. I'm 
not saying that it will, only that if it exists, the debugger seems like 
the most likely place.

But... probably not.

In any case, even if you find something that will do this, it will be 
implementation-specific (e.g. Jython only, or IronPython only, or 
CPython only, but not all three) and probably rather dubious. After all, 
any object may have zero, one or more names, in completely different 
scopes. The whole idea of "what name does this object have" is rather 
dubious. The best one can do is say "in this namespace (locals), does 
this object have any names?".


-- 
Steve

From alan.gauld at btinternet.com  Mon Apr 20 19:33:33 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Apr 2015 18:33:33 +0100
Subject: [Tutor] introspection
In-Reply-To: <53b5d70a1b929de9cad143f11802c795@sonic.net>
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
 <CAPM-O+xi2dGDsoZ8zVPZeY7vNbDM3=_-zdDqN1YJW-rfKbkUiQ@mail.gmail.com>
 <53b5d70a1b929de9cad143f11802c795@sonic.net>
Message-ID: <mh3d9b$stn$1@ger.gmane.org>

On 20/04/15 17:55, Alex Kleider wrote:

>>>>> locals()
>> {'a': 3, 'c': 3, 'b': 6, '__builtins__': <module '__builtin__'
>> (built-in)>, '__package__': None, '__name__': '__main__', '__doc__':
>> None}

> Showing my desired use case might make my question more understandable:
> def debug(var_name):
>      if args["--debug"]:
>          print("Identifier <{}> is bound to: {}"
>              .format(var_name.__name__, repr(var_name)))
> I don't think the built in locals() can help me.

Why not? Provided you pass the required scope into your function:

def debug(var_name, scope):
     if args["--debug"]:
         print("Identifier <{}> is bound to: {}"
               .format(var_name, scope.get(var_name, 'no object'))

debug('a',locals()) # look in local vars


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From __peter__ at web.de  Mon Apr 20 19:34:27 2015
From: __peter__ at web.de (Peter Otten)
Date: Mon, 20 Apr 2015 19:34:27 +0200
Subject: [Tutor] introspection
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
 <CAPM-O+xi2dGDsoZ8zVPZeY7vNbDM3=_-zdDqN1YJW-rfKbkUiQ@mail.gmail.com>
 <53b5d70a1b929de9cad143f11802c795@sonic.net>
Message-ID: <mh3db9$tp8$1@ger.gmane.org>

Alex Kleider wrote:

> On 2015-04-20 09:15, Joel Goldstick wrote:
>> On Mon, Apr 20, 2015 at 11:24 AM, Alex Kleider <akleider at sonic.net>
>> wrote:
>>> Does python provide the introspective ability to retrieve the name to
>>> which
>>> an object is bound?
>>> 
>>> For example:
>>> $ python3
>>> Python 3.4.0 (default, Apr 11 2014, 13:05:18)
>>> [GCC 4.8.2] on linux
>>> Type "help", "copyright", "credits" or "license" for more information.
>>>>>> 
>>>>>> a = 69
>>>>>> print("Identifier <{}> is bound to {}.".format(a.__name__, a))
>>> 
>>> Traceback (most recent call last):
>>>   File "<stdin>", line 1, in <module>
>>> AttributeError: 'int' object has no attribute '__name__'
>>> 
>>> 
>> An object can be bound to multiple names.  Within a namespace you can
>> use locals to see names, then compare various names like so:
>>> 
>>>>> a = 3
>>>>> b = 6
>>>>> c = a
>>>>> locals()
>> {'a': 3, 'c': 3, 'b': 6, '__builtins__': <module '__builtin__'
>> (built-in)>, '__package__': None, '__name__': '__main__', '__doc__':
>> None}
>>>>> a is b
>> False
>>>>> a is c
>> True
> 
> Showing my desired use case might make my question more understandable:
> def debug(var_name):
>      if args["--debug"]:
>          print("Identifier <{}> is bound to: {}"
>              .format(var_name.__name__, repr(var_name)))
> I don't think the built in locals() can help me.
> Thanks all the same.
> Alex

In CPython you can inspect the callstack, but remember that 

(1) it is a costly operation
(2) there are many variables bound to multiple names or none at all.

$ cat show_name_binding2.py 
import sys

def bindings_of(value, depth):
    frame = sys._getframe(depth + 1)
    bindings = [n for n, v in frame.f_locals.items() if v is value]
    if bindings:
        return bindings
    return ["<no bindings found>"]

def debug(value):
    print("{} is bound to {}".format(
        value, ", ".join(bindings_of(value, 1))))

def main():
    x = 42
    y = 42
    
    debug(42)
    debug("foo")
    
    a = "bar baz"
    b = " ".join(a.split())
    assert a == b
    debug("bar baz")

if __name__ == "__main__":
    main()
$ python3 show_name_binding2.py 
42 is bound to y, x
foo is bound to <no bindings found>
bar baz is bound to a



From fomcl at yahoo.com  Mon Apr 20 22:05:12 2015
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Mon, 20 Apr 2015 20:05:12 +0000 (UTC)
Subject: [Tutor] Is it possible to "backport" the datetime module of Python
 3.3 to Python 3.2?
Message-ID: <1793882820.317947.1429560312853.JavaMail.yahoo@mail.yahoo.com>

Hi,

My Raspberry Pi 2 comes with Python 3.2 (and 2.7). I run some code that uses the datetime module but I get an error:

"AttributeError: 'datetime.datetime' object has no attribute 'timestamp'". On https://docs.python.org/3/whatsnew/3.3.html I see: "New datetime.datetime.timestamp() method: Return POSIX timestamp corresponding to thedatetime instance." Is upgrading Python 3.3 or higher my only option, or is it somehow possible to use the newer version of the datetime library for Python 3.2? I do not want to modify the source code of the library that causes the error (pysolar).

Thanks!

 
Regards,

Albert-Jan




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a 

fresh water system, and public health, what have the Romans ever done for us?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

From ben+python at benfinney.id.au  Mon Apr 20 22:18:39 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Tue, 21 Apr 2015 06:18:39 +1000
Subject: [Tutor] sample dictionairies
References: <CALRAYNVrMGrJOFMhv3zHasiAqSr8GsFMgjn4WXZ5r1edxUhkPQ@mail.gmail.com>
 <mh29n9$p1d$1@ger.gmane.org>
 <CALRAYNVyzjSNtpa0=jRnL6Omcu0ifznqd8s_o9GiXQ5sJC3efA@mail.gmail.com>
Message-ID: <85iocqo8o0.fsf@benfinney.id.au>

Jim Mooney <cybervigilante at gmail.com> writes:

> I should have known to simply try importing csv.

Better: You should now know to refer to the documentation
<URL:https://docs.python.org/3/library/>.

-- 
 \          ?Speech is conveniently located midway between thought and |
  `\        action, where it often substitutes for both.? ?John Andrew |
_o__)                                  Holmes, _Wisdom in Small Doses_ |
Ben Finney


From ben+python at benfinney.id.au  Mon Apr 20 22:24:22 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Tue, 21 Apr 2015 06:24:22 +1000
Subject: [Tutor] introspection
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
Message-ID: <85egneo8eh.fsf@benfinney.id.au>

Alex Kleider <akleider at sonic.net> writes:

> Does python provide the introspective ability to retrieve the name to
> which an object is bound?

Objects aren't bound to names. So, no.

The binding from a reference (a name is a reference) to objects is
one-way.

See this excellent presentation from PyCon US 2015 by Ned Batchelder
<URL:https://www.youtube.com/watch?v=_AEJHKGk9ns>.

-- 
 \     ?I must say that I find television very educational. The minute |
  `\       somebody turns it on, I go to the library and read a book.? |
_o__)                                                    ?Groucho Marx |
Ben Finney


From ben+python at benfinney.id.au  Mon Apr 20 22:47:17 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Tue, 21 Apr 2015 06:47:17 +1000
Subject: [Tutor] bin to dec conversion puzzlement
References: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
Message-ID: <854moao7ca.fsf@benfinney.id.au>

Jim Mooney <cybervigilante at gmail.com> writes:

> I can't seem to get my head around this 'simple' book example of
> binary-to-decimal conversion, which goes from left to right:
>
> B = '11011101'
> I = 0
> while B:
>     I = I * 2 + int(B[0])
>     B = B[1:]
>
> print(I)
> >>> 221

That is, IMO, a needlessly confusing way to write that code.

Whoever wrote it is clearly pleased with how clever it is; but
cleverness is almost always a property of *bad* code because it's
difficult to understand at a glance. That's the case here.

One significant problem with the code as written is that it uses a
?while? loop and mutates the list, where there's no point; it should
just iterate over items *from* the list without changing it.

Another significant problem is that it uses moronically-short,
completely unexpressive names. This is Python not FORTRAN.

Try this::

    binary_text = '11011101'
    result = 0

    for binary_digit in binary_text:
        # Accumulate powers of 2 for each digit.
        result = result * 2 + int(binary_digit)

    print(result)

> Both methods work but I just can't see how the first one does. Am I
> missing something obvious here?

No, you were missing something needlessly obscured by the badly-written
code. Which book is this? I will be sure never to recommend it.

Hope that helps.

-- 
 \         ?Science is a way of trying not to fool yourself. The first |
  `\     principle is that you must not fool yourself, and you are the |
_o__)               easiest person to fool.? ?Richard P. Feynman, 1964 |
Ben Finney


From cybervigilante at gmail.com  Mon Apr 20 22:15:09 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Mon, 20 Apr 2015 13:15:09 -0700
Subject: [Tutor] bin to dec conversion puzzlement
In-Reply-To: <mh392t$e61$2@ger.gmane.org>
References: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
 <mh392t$e61$2@ger.gmane.org>
Message-ID: <CALRAYNVN7KAsuFsMs-Pmp489tMf7jAXw3BF0k8XzGVw1p=BC1A@mail.gmail.com>

 The key is that the result gets multiplied by 2 each time

> so for an N bit number the leftmost digit winds up being
> effectively 2**N, which is what you want.
>


> Alan G


Ah, the light dawns once it was restated. It would be even simpler if you
could multiply each element of the binary number by it's respective power
of two, and sum them all at once. I hear Py 3.5 will have vector abilities.
I wonder it if would do something like that.

Jim

From davea at davea.name  Tue Apr 21 01:43:51 2015
From: davea at davea.name (Dave Angel)
Date: Mon, 20 Apr 2015 19:43:51 -0400
Subject: [Tutor] bin to dec conversion puzzlement
In-Reply-To: <CALRAYNVN7KAsuFsMs-Pmp489tMf7jAXw3BF0k8XzGVw1p=BC1A@mail.gmail.com>
References: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
 <mh392t$e61$2@ger.gmane.org>
 <CALRAYNVN7KAsuFsMs-Pmp489tMf7jAXw3BF0k8XzGVw1p=BC1A@mail.gmail.com>
Message-ID: <55358F37.6030508@davea.name>

On 04/20/2015 04:15 PM, Jim Mooney wrote:
>   The key is that the result gets multiplied by 2 each time
>
>> so for an N bit number the leftmost digit winds up being
>> effectively 2**N, which is what you want.
>>
>
>
>> Alan G
>
>
> Ah, the light dawns once it was restated. It would be even simpler if you
> could multiply each element of the binary number by it's respective power
> of two, and sum them all at once. I hear Py 3.5 will have vector abilities.
> I wonder it if would do something like that.

It's important to understand these conversion methods, or I would have 
earlier mentioned that you can convert from a binary string simply by

     x = int("1011", 2)

No loop needed.


But if you need a loop for an analagous algorithm, find a way to either 
minimize the number of times through the loop, or to reduce the work 
done in each loop.

Ben's algorithm is much simpler than the one in the book you're reading.

     binary_text = '11011101'
     result = 0

     for binary_digit in binary_text:
         # Accumulate powers of 2 for each digit.
         result = result * 2 + int(binary_digit)

     print(result)

But more importantly, it's much simpler than calculating various powers 
of two and multiplying the various coefficients by them, and somehow 
"sum them all at once".


-- 
DaveA

From robertvstepp at gmail.com  Tue Apr 21 04:34:39 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 20 Apr 2015 21:34:39 -0500
Subject: [Tutor] How to close a Tkinter window from a different thread?
In-Reply-To: <mh28pc$cq5$1@ger.gmane.org>
References: <CANDiX9LVDvbYoaVSzvLJeFpjqJrKf=Yt79nNnVtKXHbZ6ooKZA@mail.gmail.com>
 <mh28pc$cq5$1@ger.gmane.org>
Message-ID: <CANDiX9+RC2yEmfM1_kkYwVMaQgTxE7iBds_saJbAUEtgc_qRZw@mail.gmail.com>

On Mon, Apr 20, 2015 at 2:10 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 20/04/15 04:34, boB Stepp wrote:
>
>> So, how do I:
>> 1) Check for the existence of an already open window from a previous
>> running of the script?
>> 2) If such a window exists, how do I close it from the new script
>> execution? And, then, of course generate a new instance of the
>> information window.
>
>
> I would suggest forgetting about windows and think about
> the processes that create them. Use the OS tools (via
> the os module) to see if the first process is still running.
> If so kill the process - which will in turn kill the window.
>
> You can find the process based on its name or based on
> its PID which you could store in a file somewhere
> (like in /tmp?)

I'm currently at home and cannot access Solaris, but I believe that
the following will do what I want:

import os
import signal
from tkinter import *

def kill():
    os.kill(pid, signal.SIGKILL)

root = Tk()
pid = os.getpid()

btn = Button(root, text='Kill me!!!', command=kill)
btn.pack()
root.mainloop()

The process id would have to be stored persistently to do the real
deal, of course, as Alan suggested. I cannot make this example work in
Windows. As far as I can tell, signal.SIGKILL won't work with Windows.
If I replace it with 9, then it does work. If I have understood what I
have read to date, using signal.SIGKILL is preferable to using 9.

Some questions:

1) Is the placement of "pid = os.getpid()" critical? My thinking is
that I want to capture the pid of the root window, store it, and then
use it if I need to kill the root and any children it has in my actual
GUI display. If, say, I placed it immediately before
"root.mainloop()", would it do what I want? Of course, I plan to
experiment with this at work tomorrow. I'll also continue to play
around with it in Windows.

2) The other possibility was to use "os.getppid" and, I suppose,
"os.kill(ppid, signal.SIGKILL)". Would this be preferable? Or will
wreak some sort of havoc?

Thanks!
boB

From akleider at sonic.net  Tue Apr 21 05:46:54 2015
From: akleider at sonic.net (Alex Kleider)
Date: Mon, 20 Apr 2015 20:46:54 -0700
Subject: [Tutor] introspection
In-Reply-To: <85egneo8eh.fsf@benfinney.id.au>
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
 <85egneo8eh.fsf@benfinney.id.au>
Message-ID: <5b61b455af3848c28968f0b83f176482@sonic.net>

On 2015-04-20 13:24, Ben Finney wrote:
> Alex Kleider <akleider at sonic.net> writes:
> 
>> Does python provide the introspective ability to retrieve the name to
>> which an object is bound?
> 
> Objects aren't bound to names. So, no.
> 
> The binding from a reference (a name is a reference) to objects is
> one-way.
> 
> See this excellent presentation from PyCon US 2015 by Ned Batchelder
> <URL:https://www.youtube.com/watch?v=_AEJHKGk9ns>.

But my code knows the name. The code is provided the name; I want the 
code to tell me that name.
..but it seems unable to do so.
;-(


From dyoo at hashcollision.org  Tue Apr 21 07:21:44 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Mon, 20 Apr 2015 22:21:44 -0700
Subject: [Tutor] introspection
In-Reply-To: <5b61b455af3848c28968f0b83f176482@sonic.net>
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
 <85egneo8eh.fsf@benfinney.id.au>
 <5b61b455af3848c28968f0b83f176482@sonic.net>
Message-ID: <CAGZAPF5ci84gkatPz8x0OD3ciorZ1Qb4AakwO6sOQuyqXUM6Tg@mail.gmail.com>

What's supposed to happen in this situation?


##########################################
class Person(object):
    def __init__(self): pass

j = Person()
john = j
jack = j
##########################################

What single name should we get back from the single Person object
here?  "j", "john", or "jack"?

From cybervigilante at gmail.com  Tue Apr 21 02:44:58 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Mon, 20 Apr 2015 17:44:58 -0700
Subject: [Tutor] enhanced subtration in an exponent
Message-ID: <CALRAYNWTgtixc694HrBqcxnrvHaNS3m94sOVNyLFB-oo3zcXqA@mail.gmail.com>

Why does the compiler choke on this? It seems to me that the enhanced
subtraction resolves to a legitimate integer in the exponent, but I get a
syntax error:

B = '11011101'
sum = 0
start = len(B)
for char in B:
    sum += int(char) * 2**(start -= 1) ## syntax error

print(sum)

-- 
Jim

From cybervigilante at gmail.com  Tue Apr 21 06:19:34 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Mon, 20 Apr 2015 21:19:34 -0700
Subject: [Tutor] calling a method directly
Message-ID: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>

Is there any difference between these two since they give the same result,
and when is the second preferred?

>>> x = 'ABE'
>>> x.lower()
'abe'
>>> str.lower(x)
'abe'

-- 
Jim

From yanglei.fage at gmail.com  Tue Apr 21 07:22:08 2015
From: yanglei.fage at gmail.com (lei yang)
Date: Tue, 21 Apr 2015 13:22:08 +0800
Subject: [Tutor] what's wrong with this ?
Message-ID: <CAHsH0E-5d_GLHm8B=_BBXaZdrqAED9DFpvuiRFL7_sCm26MK0g@mail.gmail.com>

>>>start_time = "2014-7-1"
>>> revlines = commands.getoutput("git log --pretty=format:'%ad:%an'
--date=short --since='%s' --no-merges" %start_time).strip().split('\n')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: unsupported format character 'a' (0x61) at index 26
>>>


if I directly use

revlines = commands.getoutput("git log --pretty=format:'%ad:%an'
--date=short --since='2014-7-1' --no-merges" ).strip().split('\n')

it works well

From danny.yoo at gmail.com  Tue Apr 21 09:41:15 2015
From: danny.yoo at gmail.com (Danny Yoo)
Date: Tue, 21 Apr 2015 00:41:15 -0700
Subject: [Tutor] enhanced subtration in an exponent
In-Reply-To: <CALRAYNWTgtixc694HrBqcxnrvHaNS3m94sOVNyLFB-oo3zcXqA@mail.gmail.com>
References: <CALRAYNWTgtixc694HrBqcxnrvHaNS3m94sOVNyLFB-oo3zcXqA@mail.gmail.com>
Message-ID: <CAGZAPF7=7fyFNeidT5-1LJ9tUTBaGVJ5H=LrXu5P929nCr9DSw@mail.gmail.com>

On Apr 21, 2015 12:24 AM, "Jim Mooney" <cybervigilante at gmail.com> wrote:
>
> Why does the compiler choke on this? It seems to me that the enhanced
> subtraction resolves to a legitimate integer in the exponent, but I get a
> syntax error:
>
> B = '11011101'
> sum = 0
> start = len(B)
> for char in B:
>     sum += int(char) * 2**(start -= 1) ## syntax error

Assignment is a statement.  In Python,  statements can't be composed.  In
the last line, it looks like you're trying to do two assignments, in
incrementing 'sum' and decrementing 'start'.  Try separating that into two
separate statements.

From danny.yoo at gmail.com  Tue Apr 21 09:50:14 2015
From: danny.yoo at gmail.com (Danny Yoo)
Date: Tue, 21 Apr 2015 00:50:14 -0700
Subject: [Tutor] what's wrong with this ?
In-Reply-To: <CAHsH0E-5d_GLHm8B=_BBXaZdrqAED9DFpvuiRFL7_sCm26MK0g@mail.gmail.com>
References: <CAHsH0E-5d_GLHm8B=_BBXaZdrqAED9DFpvuiRFL7_sCm26MK0g@mail.gmail.com>
Message-ID: <CAGZAPF7cCh0LEzsjM_=jTM=dL5+LUOU=d0iKpbtckVU46-1r+g@mail.gmail.com>

On Apr 21, 2015 12:27 AM, "lei yang" <yanglei.fage at gmail.com> wrote:
>
> >>>start_time = "2014-7-1"
> >>> revlines = commands.getoutput("git log --pretty=format:'%ad:%an'
> --date=short --since='%s' --no-merges" %start_time).strip().split('\n')
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> ValueError: unsupported format character 'a' (0x61) at index 26

Your format string has an embedded format string in it.  Although you may
think it obvious that Python should know not to touch the embedded format
string since there are single quotes, Python doesn't take those single
quote characters with any reverence.  Therefore, it can't tell that you
want to keep the embedded one as a literal.

Fundamentally, building a command string with string formatting is error
prone: consider the subprocess module and passing an explicit list of
arguments, rather than a single string.

From alan.gauld at btinternet.com  Tue Apr 21 10:03:58 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 21 Apr 2015 09:03:58 +0100
Subject: [Tutor] calling a method directly
In-Reply-To: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
Message-ID: <mh509c$4an$1@ger.gmane.org>

On 21/04/15 05:19, Jim Mooney wrote:
> Is there any difference between these two since they give the same result,
> and when is the second preferred?
>
>>>> x = 'ABE'
>>>> x.lower()
> 'abe'
>>>> str.lower(x)
> 'abe'
>

They are essentially the same method being accessed in two
different ways. The first via the instance,
the second via the class.

It's a  bit like when you call a superclass method in OOP:
 >>> class C:
...   def f(s): print 'in C'
...
 >>> class D(C):
...   def f(s):
...     C.f(s)
...     print 'and D'
...   def g(s): print 'only D'
...

In the first line of D.f() you invoke C's foo method
by referring to C and passing the local self as the object.

You can do it in top level code too:

 >>> d = D()
 >>> d.f()
in C
and D
 >>> C.f(d)
in C
 >>>
 >>> d.g()
only D
 >>> D.g(d)
only D

There are very few cases where the class version is preferred,
you nearly always use the instance technique.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Tue Apr 21 10:08:25 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 21 Apr 2015 09:08:25 +0100
Subject: [Tutor] what's wrong with this ?
In-Reply-To: <CAHsH0E-5d_GLHm8B=_BBXaZdrqAED9DFpvuiRFL7_sCm26MK0g@mail.gmail.com>
References: <CAHsH0E-5d_GLHm8B=_BBXaZdrqAED9DFpvuiRFL7_sCm26MK0g@mail.gmail.com>
Message-ID: <mh50ho$83n$1@ger.gmane.org>

On 21/04/15 06:22, lei yang wrote:
>>>> start_time = "2014-7-1"
>>>> revlines = commands.getoutput("git log --pretty=format:'%ad:%an'
> --date=short --since='%s' --no-merges" %start_time).strip().split('\n')
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> ValueError: unsupported format character 'a' (0x61) at index 26
>>>>

Your pretty=format argument has a %a in it.
Python tries to match percent signs to the values provided
but it doesn't know how to process %a. You need to get a
literal % sign into your string so you need to double
it up. Here is a simpler example:

 >>> "foo %%5 and %d" % 45
'foo %5 and 45'
 >>>

Alternatively use the more modern subprocess module while
helps prevent these kinds of issues by taking all
arguments as separate strings in a list.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Tue Apr 21 10:14:29 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 21 Apr 2015 09:14:29 +0100
Subject: [Tutor] enhanced subtration in an exponent
In-Reply-To: <CALRAYNWTgtixc694HrBqcxnrvHaNS3m94sOVNyLFB-oo3zcXqA@mail.gmail.com>
References: <CALRAYNWTgtixc694HrBqcxnrvHaNS3m94sOVNyLFB-oo3zcXqA@mail.gmail.com>
Message-ID: <mh50t3$e8g$1@ger.gmane.org>

On 21/04/15 01:44, Jim Mooney wrote:
> Why does the compiler choke on this? It seems to me that the enhanced
> subtraction resolves to a legitimate integer

That's your mistake. Assignment is a statement not an expression. It 
does not return anything. In fact its just illegal to try:

 >>> print x=3
   File "<stdin>", line 1
     print x=3
            ^
SyntaxError: invalid syntax
 >>>

You have to do all the assignments up front.
If you don;t need to store the new value you can just
put the subtraction as an argument:

    sum += int(char) * 2**(start-1)

But if you need start to hold that new value you must
do that assignment before using it.

BTW.
This is 'A Good Thing' since it avoids a whole class
of bug that is very common in languages like C and
encourages breaking up complex statements into
multiple lines which aids debugging, readability
and maintenance.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From __peter__ at web.de  Tue Apr 21 10:24:09 2015
From: __peter__ at web.de (Peter Otten)
Date: Tue, 21 Apr 2015 10:24:09 +0200
Subject: [Tutor] calling a method directly
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
Message-ID: <mh51fa$o4j$1@ger.gmane.org>

Jim Mooney wrote:

> Is there any difference between these two since they give the same result,
> and when is the second preferred?
> 
>>>> x = 'ABE'
>>>> x.lower()
> 'abe'
>>>> str.lower(x)
> 'abe'

You may call str.lower() explicitly for subclasses of str. If the subclass
overrides the lower() method there is a difference:
 
>>> class MyStr(str):
...     def lower(self): return "lower({!r})".format(self)
... 
>>> x = MyStr("ABC")
>>> x.lower()
"lower('ABC')"
>>> str.lower(x)
'abc'

I don't think the second form is ever preferred, but if you know in advance
that you are dealing only with strings a lazy person may sometimes write

str.lower

instead of the more conventional

def lower(s):
    return s.lower()

>>> words = "abrufen anrufen Anrufer".split()
>>> sorted(words)
['Anrufer', 'abrufen', 'anrufen']
>>> sorted(words, key=str.lower)
['abrufen', 'anrufen', 'Anrufer']
>>> sorted(words, key=lambda s: s.lower())
['abrufen', 'anrufen', 'Anrufer']

The main disadvantage of invoking an unbound method is that it defeats
"duck-typing" (the code works with every object that has a lower() method
returning a string), and that is more common and more useful than you might
think after reading the following example:

>>> class Cow:
...     def lower(self): return "moo"
...     def __repr__(self): return "<Lisa the cow>"
... 
>>> words.append(Cow())

Lisa provides the interface needed for the sort operation

>>> sorted(words, key=lambda s: s.lower())
['abrufen', 'anrufen', 'Anrufer', <Lisa the cow>]

but is not exactly a str:

>>> sorted(words, key=str.lower)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor 'lower' requires a 'str' object but received a 'Cow'

Moo ;)



From __peter__ at web.de  Tue Apr 21 10:45:51 2015
From: __peter__ at web.de (Peter Otten)
Date: Tue, 21 Apr 2015 10:45:51 +0200
Subject: [Tutor] Pun panic, was Re: calling a method directly
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org>
Message-ID: <mh52o0$d4h$1@ger.gmane.org>

Peter Otten wrote:

>>>> class Cow:
> ...     def lower(self): return "moo"

If you can't make sense of that: at the time of writing I thought that
"lowering" was a synonym for "mooing". After a look into the dictionary it 
turns out to be "lowing", not "lowering". Sorry!



From alan.gauld at btinternet.com  Tue Apr 21 11:09:50 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 21 Apr 2015 10:09:50 +0100
Subject: [Tutor] Pun panic, was Re: calling a method directly
In-Reply-To: <mh52o0$d4h$1@ger.gmane.org>
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
Message-ID: <mh544s$2ts$1@ger.gmane.org>

On 21/04/15 09:45, Peter Otten wrote:
> Peter Otten wrote:
>
>>>>> class Cow:
>> ...     def lower(self): return "moo"
>
> If you can't make sense of that: at the time of writing I thought that
> "lowering" was a synonym for "mooing". After a look into the dictionary it
> turns out to be "lowing", not "lowering". Sorry!

:-)

I thought you were just being a bit random!


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From davea at davea.name  Tue Apr 21 12:40:05 2015
From: davea at davea.name (Dave Angel)
Date: Tue, 21 Apr 2015 06:40:05 -0400
Subject: [Tutor] introspection
In-Reply-To: <CAGZAPF5ci84gkatPz8x0OD3ciorZ1Qb4AakwO6sOQuyqXUM6Tg@mail.gmail.com>
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
 <85egneo8eh.fsf@benfinney.id.au> <5b61b455af3848c28968f0b83f176482@sonic.net>
 <CAGZAPF5ci84gkatPz8x0OD3ciorZ1Qb4AakwO6sOQuyqXUM6Tg@mail.gmail.com>
Message-ID: <55362905.2070204@davea.name>

On 04/21/2015 01:21 AM, Danny Yoo wrote:
> What's supposed to happen in this situation?
>
>
> ##########################################
> class Person(object):
>      def __init__(self): pass
>
> j = Person()
> john = j
> jack = j
> ##########################################
>
> What single name should we get back from the single Person object
> here?  "j", "john", or "jack"?


And what name should you get from the second Person() object created here?

mylist = [Person(), Person(), Person()]




-- 
DaveA

From davea at davea.name  Tue Apr 21 12:55:21 2015
From: davea at davea.name (Dave Angel)
Date: Tue, 21 Apr 2015 06:55:21 -0400
Subject: [Tutor] enhanced subtration in an exponent
In-Reply-To: <CALRAYNWTgtixc694HrBqcxnrvHaNS3m94sOVNyLFB-oo3zcXqA@mail.gmail.com>
References: <CALRAYNWTgtixc694HrBqcxnrvHaNS3m94sOVNyLFB-oo3zcXqA@mail.gmail.com>
Message-ID: <55362C99.4060505@davea.name>

On 04/20/2015 08:44 PM, Jim Mooney wrote:
> Why does the compiler choke on this? It seems to me that the enhanced
> subtraction resolves to a legitimate integer in the exponent, but I get a
> syntax error:
>
> B = '11011101'
> sum = 0
> start = len(B)
> for char in B:
>      sum += int(char) * 2**(start -= 1) ## syntax error
>
> print(sum)
>

As others have said, the augmented assignment, like the regular 
assignment, is not permissible inside an expression.  It is a type of 
statement.

You could solve this easily enough by:


B = '11011101'
sum = 0
start = len(B)
for index, char in enumerate(B):
     sum += int(char) * 2**(start - index)

print(sum)


But I'd think that:

B = '11011101'
sum = 0
for char in B:
     sum = sum * 2 + int(char)

print(sum)

reads much better, as well as being much faster.



-- 
DaveA

From breamoreboy at yahoo.co.uk  Tue Apr 21 13:31:53 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Tue, 21 Apr 2015 12:31:53 +0100
Subject: [Tutor] Is it possible to "backport" the datetime module of
 Python 3.3 to Python 3.2?
In-Reply-To: <1793882820.317947.1429560312853.JavaMail.yahoo@mail.yahoo.com>
References: <1793882820.317947.1429560312853.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <mh5cfb$jcu$1@ger.gmane.org>

On 20/04/2015 21:05, Albert-Jan Roskam wrote:
> Hi,
>
> My Raspberry Pi 2 comes with Python 3.2 (and 2.7). I run some code that uses the datetime module but I get an error:
>
> "AttributeError: 'datetime.datetime' object has no attribute 'timestamp'". On https://docs.python.org/3/whatsnew/3.3.html I see: "New datetime.datetime.timestamp() method: Return POSIX timestamp corresponding to thedatetime instance." Is upgrading Python 3.3 or higher my only option, or is it somehow possible to use the newer version of the datetime library for Python 3.2? I do not want to modify the source code of the library that causes the error (pysolar).
>
> Thanks!
>
>
> Regards,
>
> Albert-Jan
>
>

Python is very strong in guaranteeing backward compatibility, so why not 
copy the 3.3 pure Python code to your 3.2 setup and see what happens?

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From breamoreboy at yahoo.co.uk  Tue Apr 21 13:33:09 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Tue, 21 Apr 2015 12:33:09 +0100
Subject: [Tutor] bin to dec conversion puzzlement
In-Reply-To: <854moao7ca.fsf@benfinney.id.au>
References: <CALRAYNUy6MHqahRiGS8LNJHLT+BR+7vY+9Npq5bnmqkWg+EYEA@mail.gmail.com>
 <854moao7ca.fsf@benfinney.id.au>
Message-ID: <mh5chn$jcu$2@ger.gmane.org>

On 20/04/2015 21:47, Ben Finney wrote:
> Jim Mooney <cybervigilante at gmail.com> writes:
>
>> I can't seem to get my head around this 'simple' book example of
>> binary-to-decimal conversion, which goes from left to right:
>>
>> B = '11011101'
>> I = 0
>> while B:
>>      I = I * 2 + int(B[0])
>>      B = B[1:]
>>
>> print(I)
>>>>> 221
>
> That is, IMO, a needlessly confusing way to write that code.
>
> Whoever wrote it is clearly pleased with how clever it is; but
> cleverness is almost always a property of *bad* code because it's
> difficult to understand at a glance. That's the case here.
>
> One significant problem with the code as written is that it uses a
> ?while? loop and mutates the list, where there's no point; it should
> just iterate over items *from* the list without changing it.
>
> Another significant problem is that it uses moronically-short,
> completely unexpressive names. This is Python not FORTRAN.
>
> Try this::
>
>      binary_text = '11011101'
>      result = 0
>
>      for binary_digit in binary_text:
>          # Accumulate powers of 2 for each digit.
>          result = result * 2 + int(binary_digit)
>
>      print(result)
>
>> Both methods work but I just can't see how the first one does. Am I
>> missing something obvious here?
>
> No, you were missing something needlessly obscured by the badly-written
> code. Which book is this? I will be sure never to recommend it.
>
> Hope that helps.
>

I agree entirely so a big +1 from me.


-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From fomcl at yahoo.com  Tue Apr 21 13:55:16 2015
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Tue, 21 Apr 2015 11:55:16 +0000 (UTC)
Subject: [Tutor] Is it possible to "backport" the datetime module of
 Python 3.3 to Python 3.2?
In-Reply-To: <mh5cfb$jcu$1@ger.gmane.org>
References: <mh5cfb$jcu$1@ger.gmane.org>
Message-ID: <1286807158.508134.1429617316517.JavaMail.yahoo@mail.yahoo.com>





----- Original Message -----
> From: Mark Lawrence <breamoreboy at yahoo.co.uk>
> To: tutor at python.org
> Cc: 
> Sent: Tuesday, April 21, 2015 1:31 PM
> Subject: Re: [Tutor] Is it possible to "backport" the datetime module of Python 3.3 to Python 3.2?
> 
> On 20/04/2015 21:05, Albert-Jan Roskam wrote:
> 
>>  Hi,
>> 
>>  My Raspberry Pi 2 comes with Python 3.2 (and 2.7). I run some code that 
> uses the datetime module but I get an error:
>> 
>>  "AttributeError: 'datetime.datetime' object has no attribute 
> 'timestamp'". On https://docs.python.org/3/whatsnew/3.3.html I see: 
> "New datetime.datetime.timestamp() method: Return POSIX timestamp 
> corresponding to thedatetime instance." Is upgrading Python 3.3 or higher 
> my only option, or is it somehow possible to use the newer version of the 
> datetime library for Python 3.2? I do not want to modify the source code of the 
> library that causes the error (pysolar).
>> 
>>  Thanks!
>> 
>> 
>>  Regards,
>> 
>>  Albert-Jan
>> 
>> 
> 
> Python is very strong in guaranteeing backward compatibility, so why not 
> copy the 3.3 pure Python code to your 3.2 setup and see what happens?



Hmmm, nice idea. Never thought about that. Well, last night (before I saw your reply) I decided to download & compile Python 3.4, because I was afraid that this error might be the tip of the iceberg. Luckily, compiling the code went surprisingly fast on that little computer! I had to do it twice, though, because I got an error about _ssl (maybe with ensurepip?). I fixed it using "sudo apt-get install libssl-dev", but isn't the following the Offical Way (tm) to do this? Are there any more errors lurking in my Python 3.4 now? *) How do I find out the URL of the entry?


pi at raspberrypi ~ $ sudo apt-get build-dep python3.4
Reading package lists... Done
Building dependency tree 
Reading state information... Done
E: You must put some 'source' URIs in your sources.list


*) Argh, while writing this I can confirm that this is still not a good installation:

pi at raspberrypi ~ $ python3.4 -c "import sqlite3" 
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/lib/python3.4/sqlite3/__init__.py", line 23, in <module>
from sqlite3.dbapi2 import *
File "/usr/local/lib/python3.4/sqlite3/dbapi2.py", line 27, in <module>
from _sqlite3 import *
ImportError: No module named '_sqlite3'



Probably this will work, but I will *never* be able to remember all these packages, so an entry in sources.list will be much nicer:
https://github.com/yyuu/pyenv/wiki/Common-build-problems

Best wishes,
Albert-Jan

From steve at pearwood.info  Tue Apr 21 14:50:22 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Tue, 21 Apr 2015 22:50:22 +1000
Subject: [Tutor] Is it possible to "backport" the datetime module of
	Python 3.3 to Python 3.2?
In-Reply-To: <mh5cfb$jcu$1@ger.gmane.org>
References: <1793882820.317947.1429560312853.JavaMail.yahoo@mail.yahoo.com>
 <mh5cfb$jcu$1@ger.gmane.org>
Message-ID: <20150421125022.GL5663@ando.pearwood.info>

On Tue, Apr 21, 2015 at 12:31:53PM +0100, Mark Lawrence wrote:

> Python is very strong in guaranteeing backward compatibility, so why not 
> copy the 3.3 pure Python code to your 3.2 setup and see what happens?

Normally backwards compatibility refers to the other way: 3.3 will run 
3.2 code. To have 3.2 run 3.3 code is *forward compatibility*.


-- 
Steve

From martin at linux-ip.net  Tue Apr 21 16:09:51 2015
From: martin at linux-ip.net (Martin A. Brown)
Date: Tue, 21 Apr 2015 07:09:51 -0700
Subject: [Tutor] Pun panic, was Re: calling a method directly
In-Reply-To: <mh52o0$d4h$1@ger.gmane.org>
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
Message-ID: <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>


Good morning underscore underscore Peter underscore underscore,

>>>>> class Cow:
>> ...     def lower(self): return "moo"
>
> If you can't make sense of that: at the time of writing I thought 
> that "lowering" was a synonym for "mooing".  After a look into the 
> dictionary it turns out to be "lowing", not "lowering". Sorry!

I, too, assumed an amusingly random example.  I simply imagined a 
maladjusted bovine Lisa suspended ominously beneath the clouds. 
Your Lisa must not be just a lowing (synonym 'mooing') cow, she must 
also be a lowering cow.

   to lower (v.i.), to be or become dark, gloomy, and threatening
     (which is cognate to the contemporary German word 'lauern')

And, I dairy not chase this pun any further....

-Martin

  [0] http://www.merriam-webster.com/dictionary/lower

-- 
Martin A. Brown
http://linux-ip.net/

From marc.tompkins at gmail.com  Tue Apr 21 18:23:19 2015
From: marc.tompkins at gmail.com (Marc Tompkins)
Date: Tue, 21 Apr 2015 09:23:19 -0700
Subject: [Tutor] Pun panic, was Re: calling a method directly
In-Reply-To: <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
 <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
Message-ID: <CAKK8jXbrZt-aFb75SV_UvM0FkJ7j1JB6SGL++u-nJd0KwdHA-A@mail.gmail.com>

On Tue, Apr 21, 2015 at 7:09 AM, Martin A. Brown <martin at linux-ip.net>
wrote:

> And, I dairy not chase this pun any further....
>

No - keep milking it.  It gets butter all the time.

From akleider at sonic.net  Tue Apr 21 18:59:32 2015
From: akleider at sonic.net (Alex Kleider)
Date: Tue, 21 Apr 2015 09:59:32 -0700
Subject: [Tutor] introspection
In-Reply-To: <CAGZAPF5ci84gkatPz8x0OD3ciorZ1Qb4AakwO6sOQuyqXUM6Tg@mail.gmail.com>
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
 <85egneo8eh.fsf@benfinney.id.au>
 <5b61b455af3848c28968f0b83f176482@sonic.net>
 <CAGZAPF5ci84gkatPz8x0OD3ciorZ1Qb4AakwO6sOQuyqXUM6Tg@mail.gmail.com>
Message-ID: <79ac40ca7483661a26e183d3c6a6b524@sonic.net>

On 2015-04-20 22:21, Danny Yoo wrote:
> What's supposed to happen in this situation?
> 
> 
> ##########################################
> class Person(object):
>     def __init__(self): pass
> 
> j = Person()
> john = j
> jack = j
> ##########################################
> 
> What single name should we get back from the single Person object
> here?  "j", "john", or "jack"?

I was hoping that it would be possible to create a function
that would do the following:

def my_name(some_object):
   return some_object.__name__

so, using what you entered above..
>>> my_name(j)
'j'
>>> my_name(john)
'john'
>>> my_name(jack)
'jack'

But I see what I think you and others have been trying to explain to me: 
that the expression some_object.__name__, if it existed, would indeed be 
schizophrenic since it would be an attribute of the object, not the 
name(s) to which  it is bound.

Thanks all for your replies.
ak

From dyoo at hashcollision.org  Tue Apr 21 19:20:45 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 21 Apr 2015 10:20:45 -0700
Subject: [Tutor] introspection
In-Reply-To: <79ac40ca7483661a26e183d3c6a6b524@sonic.net>
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
 <85egneo8eh.fsf@benfinney.id.au>
 <5b61b455af3848c28968f0b83f176482@sonic.net>
 <CAGZAPF5ci84gkatPz8x0OD3ciorZ1Qb4AakwO6sOQuyqXUM6Tg@mail.gmail.com>
 <79ac40ca7483661a26e183d3c6a6b524@sonic.net>
Message-ID: <CAGZAPF5t0ZJL64o6J_cYUwjQgDkC_+x6AyZYG-fQuJhsz95r0A@mail.gmail.com>

> But I see what I think you and others have been trying to explain to me:
> that the expression some_object.__name__, if it existed, would indeed be
> schizophrenic since it would be an attribute of the object, not the name(s)
> to which  it is bound.


The hypothetical feature might also, if designed badly, break simple
things like checking for equality.  e.g. say that we do:

    x = # ... some value
    y = copy.deepcopy(x)

Would x == y?  From my understanding, if the object were automatically
associating a __name__, it should not.  And that would be weird.  :P

This is not to say that what you're asking for is unreasonable!   It's
just that Python doesn't do it, and introducing such a feature in
Python would have large implications in terms of what it means, not to
mention how it might affect the runtime.

From anton.garou at gmail.com  Tue Apr 21 15:01:39 2015
From: anton.garou at gmail.com (Opher Lubzens)
Date: Tue, 21 Apr 2015 16:01:39 +0300
Subject: [Tutor] handling exception raising in atexit registered function
Message-ID: <CAKw=SkzBn-4J-sUBvuoC8qW_U6xF=UQM2aK5Tr1iQDe70JatoA@mail.gmail.com>

Hi, I am developing an automated testing script in python which will, among
other things, send an email when it is done. For this I would like to send
an email when an exception is raised as well - since it already has a
cleanup function registered with atexit, this is the logical place to do
it. However, I didn't find a good HOWTO on a cleanup function like that
identifying an exception has been raised and reacting to it.

thanks,
Opher

From cory.smith14 at outlook.com  Tue Apr 21 13:17:23 2015
From: cory.smith14 at outlook.com (Ryan Scholes)
Date: Tue, 21 Apr 2015 12:17:23 +0100
Subject: [Tutor] ?!
Message-ID: <BLU181-W955DBADE924AB6C5554D069BEF0@phx.gbl>

 Hi, 
 
Didn't really understand the instructions on the website but is this the right email address for help? 
 
Thanks, cory :) 
 		 	   		  

From memilanuk at gmail.com  Tue Apr 21 20:26:33 2015
From: memilanuk at gmail.com (memilanuk)
Date: Tue, 21 Apr 2015 11:26:33 -0700
Subject: [Tutor] ?!
In-Reply-To: <BLU181-W955DBADE924AB6C5554D069BEF0@phx.gbl>
References: <BLU181-W955DBADE924AB6C5554D069BEF0@phx.gbl>
Message-ID: <mh64oq$838$1@ger.gmane.org>

On 04/21/2015 04:17 AM, Ryan Scholes wrote:
>   Hi,
>
> Didn't really understand the instructions on the website but is this the right email address for help?
>

It can be...

Some very smart, experienced and helpful folks here - some are even all 
three! ;)

Generally speaking... they aren't going to do your (home) work for 
you... try to provide some code to show what you've tried, and specific 
questions as to what you're having trouble with.


-- 
Shiny!  Let's be bad guys.

Reach me @ memilanuk (at) gmail dot com


From alan.gauld at btinternet.com  Tue Apr 21 20:51:53 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 21 Apr 2015 19:51:53 +0100
Subject: [Tutor] ?!
In-Reply-To: <BLU181-W955DBADE924AB6C5554D069BEF0@phx.gbl>
References: <BLU181-W955DBADE924AB6C5554D069BEF0@phx.gbl>
Message-ID: <mh6687$1j6$1@ger.gmane.org>

On 21/04/15 12:17, Ryan Scholes wrote:

> Didn't really understand the instructions on the website but is this the right email address for help?

If its help about:
a) learning to program
b) learning the Python programming language
c) learning the Python standard library

Then yes, this is the right place.

Ask questions. Tell us what OS you use, what version
of Python and if you have an error message cut n paste
it into the email.

We will try to answer for you or at least point you
in the right direction.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From ben+python at benfinney.id.au  Wed Apr 22 01:27:02 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 22 Apr 2015 09:27:02 +1000
Subject: [Tutor] Pun panic
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
 <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
Message-ID: <85lhhlm5a1.fsf_-_@benfinney.id.au>

"Martin A. Brown" <martin at linux-ip.net> writes:

> Good morning underscore underscore Peter underscore underscore,

The Pythonic way to pronounce that would be ?dunder Pete dunder?
<URL:https://wiki.python.org/moin/DunderAlias>.

-- 
 \         ?Geeks like to think that they can ignore politics. You can |
  `\        leave politics alone, but politics won't leave you alone.? |
_o__)                                 ?Richard M. Stallman, 2002-07-26 |
Ben Finney


From ben+python at benfinney.id.au  Wed Apr 22 01:38:18 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 22 Apr 2015 09:38:18 +1000
Subject: [Tutor] introspection
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
 <85egneo8eh.fsf@benfinney.id.au>
 <5b61b455af3848c28968f0b83f176482@sonic.net>
 <CAGZAPF5ci84gkatPz8x0OD3ciorZ1Qb4AakwO6sOQuyqXUM6Tg@mail.gmail.com>
 <79ac40ca7483661a26e183d3c6a6b524@sonic.net>
Message-ID: <85fv7tm4r9.fsf@benfinney.id.au>

Alex Kleider <akleider at sonic.net> writes:

> I was hoping that it would be possible to create a function
> that would do the following:
>
> def my_name(some_object):
>   return some_object.__name__

That hope is understandable.

It is also easy to be confused about why such a feature doesn't exist;
after all, it works for functions and classes and modules (oh my!)::

    >>> def foo(): pass
    ... 
    >>> foo.__name__
    'foo'
    >>> class Bar: pass
    ... 
    >>> Bar.__name__
    'Bar'
    >>> import sys
    >>> sys.__name__
    'sys'

So why not arbitrary objects?

    >>> spam = 4
    >>> spam.__name__
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'int' object has no attribute '__name__'

The answer is that functions, classes, and modules are all *defined*,
and (normally) have exactly one canonical name established at definition
time.

Arbitrary objects are merely *instantiated*, without that definition
step. Quite commonly they are used with no name bound to them; so the
behaviour of most objects does not have ?__name__? in the API.

If you would like to make a class that has that attribute on all its
instances, feel free. But you need to figure out how the instance
detects its own name!

    class LockeanThing:
        """ An object that knows the name by which others refer to it. """

        def __init__(self):
            self.__name__ = ???

> But I see what I think you and others have been trying to explain to
> me: that the expression some_object.__name__, if it existed, would
> indeed be schizophrenic since it would be an attribute of the object,
> not the name(s) to which it is bound.

That's why I prefer to be clear that the binding operation is one-way
only.

A reference (such as a name) is bound to an object, the object is not
bound to the reference ? indeed, the object knows nothing about that
relationship.

-- 
 \        ?I washed a sock. Then I put it in the dryer. When I took it |
  `\                                 out, it was gone.? ?Steven Wright |
_o__)                                                                  |
Ben Finney


From cs at zip.com.au  Wed Apr 22 01:48:03 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Wed, 22 Apr 2015 09:48:03 +1000
Subject: [Tutor] introspection
In-Reply-To: <79ac40ca7483661a26e183d3c6a6b524@sonic.net>
References: <79ac40ca7483661a26e183d3c6a6b524@sonic.net>
Message-ID: <20150421234803.GA37521@cskk.homeip.net>

On 21Apr2015 09:59, Alex Kleider <akleider at sonic.net> wrote:
>On 2015-04-20 22:21, Danny Yoo wrote:
>>What's supposed to happen in this situation?
>>##########################################
>>class Person(object):
>>    def __init__(self): pass
>>
>>j = Person()
>>john = j
>>jack = j
>>##########################################
>>
>>What single name should we get back from the single Person object
>>here?  "j", "john", or "jack"?
>
>I was hoping that it would be possible to create a function
>that would do the following:
>
>def my_name(some_object):
>  return some_object.__name__
>
>so, using what you entered above..
>>>>my_name(j)
>'j'
>>>>my_name(john)
>'john'
>>>>my_name(jack)
>'jack'
>
>But I see what I think you and others have been trying to explain to 
>me: that the expression some_object.__name__, if it existed, would 
>indeed be schizophrenic since it would be an attribute of the object, 
>not the name(s) to which  it is bound.

But it would not be schizophrenic to write a function that returned a name 
arbitrarily, by inspecting locals(). It depends whether you only need a name, 
or if you need "the" name.

Write yourself a "find_name_from_locals(local_map, value)" function that 
reports. That will (a) get you a partial answer and (b) cement in your mind 
what is possible and why. Easy and useful!

Cheers,
Cameron Simpson <cs at zip.com.au>

Technique will get you through times of no strength a lot better than
strength will get you through times of no technique.    - the Nealomatic

From cs at zip.com.au  Wed Apr 22 01:59:51 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Wed, 22 Apr 2015 09:59:51 +1000
Subject: [Tutor] calling a method directly
In-Reply-To: <mh509c$4an$1@ger.gmane.org>
References: <mh509c$4an$1@ger.gmane.org>
Message-ID: <20150421235951.GA61397@cskk.homeip.net>

On 21Apr2015 09:03, alan.gauld at btinternet.com <alan.gauld at btinternet.com> wrote:
>On 21/04/15 05:19, Jim Mooney wrote:
>>Is there any difference between these two since they give the same result,
>>and when is the second preferred?
>>
>>>>>x = 'ABE'
>>>>>x.lower()
>>'abe'
>>>>>str.lower(x)
>>'abe'
>
>They are essentially the same method being accessed in two
>different ways.
>The first via the instance,
>the second via the class.

Though only because 'x' is directly a str. Not some other class. In Jim's 
example we _know_ 'x' is a str. In general one is less sure, and often one 
hopes not to care!

>It's a  bit like when you call a superclass method in OOP:
>>>> class C:
>...   def f(s): print 'in C'
>...
>>>> class D(C):
>...   def f(s):
>...     C.f(s)
>...     print 'and D'
>...   def g(s): print 'only D'
>...
>
>In the first line of D.f() you invoke C's foo method
>by referring to C and passing the local self as the object.

Worth pointing out that this is almost always the only time you cant to call 
via the class directly. And that it is actually common in subclass method 
implementations, particularly __init__, where on must often go:

  class D(C):
    def __init__(self, blah...):
      # initialise the common "C" class related stuff
      C.__init__(self, ...)
      # intialise the specific "D" class related stuff
      ... D-specific-stuff-here ...

[...]
>There are very few cases where the class version is preferred,
>you nearly always use the instance technique.

Indeed. Not least because (a) you don't always know or even care what class an 
object is and (b) objects themselves can have callable attributes.

Cheers,
Cameron Simpson <cs at zip.com.au>

Applications Programming is for dullards who can't do Systems Programming.
        - David Rose, dave at werple.apana.org.au

From cs at zip.com.au  Wed Apr 22 02:25:48 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Wed, 22 Apr 2015 10:25:48 +1000
Subject: [Tutor] Is it possible to "backport" the datetime module of
 Python 3.3 to Python 3.2?
In-Reply-To: <20150421125022.GL5663@ando.pearwood.info>
References: <20150421125022.GL5663@ando.pearwood.info>
Message-ID: <20150422002548.GA33929@cskk.homeip.net>

On 21Apr2015 22:50, Steven D'Aprano <steve at pearwood.info> wrote:
>On Tue, Apr 21, 2015 at 12:31:53PM +0100, Mark Lawrence wrote:
>
>> Python is very strong in guaranteeing backward compatibility, so why not
>> copy the 3.3 pure Python code to your 3.2 setup and see what happens?
>
>Normally backwards compatibility refers to the other way: 3.3 will run
>3.2 code. To have 3.2 run 3.3 code is *forward compatibility*.

Yes, but it can depend on where you stand.

Mark was talking about taking the 3.3 datetime module code and running it on 
3.2. So in this context, he is suggesting that the _code_ in the 3.3 datetime 
module is probably backward compatible - it has presents features but does not 
depend on 3.3 aspects of the language, and therefore may well run on 3.2.

Cheers,
Cameron Simpson <cs at zip.com.au>

The most annoying thing about being without my files after our disc crash was
discovering once again how widespread BLINK was on the web.

From akleider at sonic.net  Wed Apr 22 03:04:05 2015
From: akleider at sonic.net (Alex Kleider)
Date: Tue, 21 Apr 2015 18:04:05 -0700
Subject: [Tutor] introspection
In-Reply-To: <20150421234803.GA37521@cskk.homeip.net>
References: <79ac40ca7483661a26e183d3c6a6b524@sonic.net>
 <20150421234803.GA37521@cskk.homeip.net>
Message-ID: <bd69b1adb441ed8dd12d18f11dbac23c@sonic.net>

On 2015-04-21 16:48, Cameron Simpson wrote:

> But it would not be schizophrenic to write a function that returned a
> name arbitrarily, by inspecting locals(). It depends whether you only
> need a name, or if you need "the" name.

In my use case there'd probably be only one name for the given object so
I believe you've given me my next exercise!

> 
> Write yourself a "find_name_from_locals(local_map, value)" function
> that reports. That will (a) get you a partial answer and (b) cement in
> your mind what is possible and why. Easy and useful!

I'll get working on that!


> 
> Cheers,
> Cameron Simpson <cs at zip.com.au>
> 
> Technique will get you through times of no strength a lot better than
> strength will get you through times of no technique.    - the 
> Nealomatic
Wonderful quote by the way!


From akleider at sonic.net  Wed Apr 22 03:12:47 2015
From: akleider at sonic.net (Alex Kleider)
Date: Tue, 21 Apr 2015 18:12:47 -0700
Subject: [Tutor] introspection
In-Reply-To: <85fv7tm4r9.fsf@benfinney.id.au>
References: <b87858c6b8ba8f79d9f80a73d2b3f6c0@sonic.net>
 <85egneo8eh.fsf@benfinney.id.au>
 <5b61b455af3848c28968f0b83f176482@sonic.net>
 <CAGZAPF5ci84gkatPz8x0OD3ciorZ1Qb4AakwO6sOQuyqXUM6Tg@mail.gmail.com>
 <79ac40ca7483661a26e183d3c6a6b524@sonic.net>
 <85fv7tm4r9.fsf@benfinney.id.au>
Message-ID: <507adf67fed517638a7530acc8f66764@sonic.net>

On 2015-04-21 16:38, Ben Finney wrote:

> That hope is understandable.
> 
Your "understanding" is appreciated.

> It is also easy to be confused ....

So true, but with the help of "Python Tutors" things are being 
rectified!

about why such a feature doesn't exist;

> So why not arbitrary objects?
> 

> The answer is that functions, classes, and modules are all *defined*,
> and (normally) have exactly one canonical name established at 
> definition
> time.
> 
> Arbitrary objects are merely *instantiated*, without that definition
> step. Quite commonly they are used with no name bound to them; so the
> behaviour of most objects does not have ?__name__? in the API.
> 
> If you would like to make a class that has that attribute on all its
> instances, feel free. But you need to figure out how the instance
> detects its own name!
> 
>     class LockeanThing:
>         """ An object that knows the name by which others refer to it. 
> """
> 
>         def __init__(self):
>             self.__name__ = ???
> 
>> But I see what I think you and others have been trying to explain to
>> me: that the expression some_object.__name__, if it existed, would
>> indeed be schizophrenic since it would be an attribute of the object,
>> not the name(s) to which it is bound.
> 
> That's why I prefer to be clear that the binding operation is one-way
> only.
> 
> A reference (such as a name) is bound to an object, the object is not
> bound to the reference ? indeed, the object knows nothing about that
> relationship.

It's sinking in.  Thank you.
ak

From __peter__ at web.de  Wed Apr 22 08:56:45 2015
From: __peter__ at web.de (Peter Otten)
Date: Wed, 22 Apr 2015 08:56:45 +0200
Subject: [Tutor] Pun panic
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
 <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
 <85lhhlm5a1.fsf_-_@benfinney.id.au>
Message-ID: <mh7gne$lff$1@ger.gmane.org>

Ben Finney wrote:

> "Martin A. Brown" <martin at linux-ip.net> writes:
> 
>> Good morning underscore underscore Peter underscore underscore,
> 
> The Pythonic way to pronounce that would be ?dunder Pete dunder?
> <URL:https://wiki.python.org/moin/DunderAlias>.
> 

Hm, should I campaign for a peter() builtin?


From ben+python at benfinney.id.au  Wed Apr 22 09:28:43 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 22 Apr 2015 17:28:43 +1000
Subject: [Tutor] Pun panic
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
 <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
 <85lhhlm5a1.fsf_-_@benfinney.id.au> <mh7gne$lff$1@ger.gmane.org>
Message-ID: <85r3rcliz8.fsf@benfinney.id.au>

Peter Otten <__peter__ at web.de> writes:

> Ben Finney wrote:
>
> > The Pythonic way to pronounce that would be ?dunder Pete dunder?
> > <URL:https://wiki.python.org/moin/DunderAlias>.
>
> Hm, should I campaign for a peter() builtin?

You'll need a working implementation first. Put it on BullCodes
<URL:https://bull.codes/> for bonus Python-based free-software
repository hosting points!

-- 
 \                             ?I'm a born-again atheist.? ?Gore Vidal |
  `\                                                                   |
_o__)                                                                  |
Ben Finney


From fomcl at yahoo.com  Wed Apr 22 11:03:50 2015
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Wed, 22 Apr 2015 09:03:50 +0000 (UTC)
Subject: [Tutor] Pun panic
In-Reply-To: <85r3rcliz8.fsf@benfinney.id.au>
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
 <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
 <85lhhlm5a1.fsf_-_@benfinney.id.au> <mh7gne$lff$1@ger.gmane.org>
 <85r3rcliz8.fsf@benfinney.id.au>
Message-ID: <1782039505.901202.1429693431007.JavaMail.yahoo@mail.yahoo.com>






----- Original Message -----
> From: Ben Finney <ben+python at benfinney.id.au>
> To: tutor at python.org
> Cc: 
> Sent: Wednesday, April 22, 2015 9:28 AM
> Subject: Re: [Tutor] Pun panic
> 
> Peter Otten <__peter__ at web.de> writes:
> 
>>  Ben Finney wrote:
>> 
>>  > The Pythonic way to pronounce that would be ?dunder Pete dunder?
>>  > <URL:https://wiki.python.org/moin/DunderAlias>.
>> 
>>  Hm, should I campaign for a peter() builtin?
> 
> You'll need a working implementation first. Put it on BullCodes
> <URL:https://bull.codes/> for bonus Python-based free-software
> repository hosting points!



Is bull.codes better than Github or Bitbucket? Does it work with Travis CI and Appveyor?

From breamoreboy at yahoo.co.uk  Wed Apr 22 13:01:46 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 22 Apr 2015 12:01:46 +0100
Subject: [Tutor] Pun panic
In-Reply-To: <mh7gne$lff$1@ger.gmane.org>
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
 <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
 <85lhhlm5a1.fsf_-_@benfinney.id.au> <mh7gne$lff$1@ger.gmane.org>
Message-ID: <mh7v2s$f42$1@ger.gmane.org>

On 22/04/2015 07:56, Peter Otten wrote:
> Ben Finney wrote:
>
>> "Martin A. Brown" <martin at linux-ip.net> writes:
>>
>>> Good morning underscore underscore Peter underscore underscore,
>>
>> The Pythonic way to pronounce that would be ?dunder Pete dunder?
>> <URL:https://wiki.python.org/moin/DunderAlias>.
>>
>
> Hm, should I campaign for a peter() builtin?
>

Only if you provide an itertools version first :)

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From ben+python at benfinney.id.au  Wed Apr 22 14:40:15 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 22 Apr 2015 22:40:15 +1000
Subject: [Tutor] Pun panic
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
 <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
 <85lhhlm5a1.fsf_-_@benfinney.id.au> <mh7gne$lff$1@ger.gmane.org>
 <85r3rcliz8.fsf@benfinney.id.au>
 <1782039505.901202.1429693431007.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <85mw20l4k0.fsf@benfinney.id.au>

Albert-Jan Roskam <fomcl at yahoo.com.dmarc.invalid> writes:

> ----- Original Message -----
> > From: Ben Finney <ben+python at benfinney.id.au>
> > You'll need a working implementation first. Put it on BullCodes
> > <URL:https://bull.codes/> for bonus Python-based free-software
> > repository hosting points!
>
> Is bull.codes better than Github or Bitbucket?

Yes, because those are not free software.

    <URL:http://mako.cc/writing/hill-free_tools.html>

Kallithea (which is what powers BullCodes) is free software, meaning
anyone is free to see how it works and change it and run their own
instance and share changes.

    <URL:http://kallithea-scm.org/>

> Does it work with Travis CI and Appveyor?

Not until the Kallithea community adds that support. Since it is free
software that's more likely than if it were proprietary :-)

-- 
 \      ?Reichel's Law: A body on vacation tends to remain on vacation |
  `\            unless acted upon by an outside force.? ?Carol Reichel |
_o__)                                                                  |
Ben Finney


From akleider at sonic.net  Wed Apr 22 17:52:37 2015
From: akleider at sonic.net (Alex Kleider)
Date: Wed, 22 Apr 2015 08:52:37 -0700
Subject: [Tutor] Pun panic
In-Reply-To: <85mw20l4k0.fsf@benfinney.id.au>
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
 <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
 <85lhhlm5a1.fsf_-_@benfinney.id.au> <mh7gne$lff$1@ger.gmane.org>
 <85r3rcliz8.fsf@benfinney.id.au>
 <1782039505.901202.1429693431007.JavaMail.yahoo@mail.yahoo.com>
 <85mw20l4k0.fsf@benfinney.id.au>
Message-ID: <819536b8284f6656b4894d550c0e21e8@sonic.net>

On 2015-04-22 05:40, Ben Finney wrote:
> Albert-Jan Roskam <fomcl at yahoo.com.dmarc.invalid> writes:
> 
>> ----- Original Message -----
>> > From: Ben Finney <ben+python at benfinney.id.au>
>> > You'll need a working implementation first. Put it on BullCodes
>> > <URL:https://bull.codes/> for bonus Python-based free-software
>> > repository hosting points!
>> 
>> Is bull.codes better than Github or Bitbucket?
> 
> Yes, because those are not free software.
> 
>     <URL:http://mako.cc/writing/hill-free_tools.html>
> 
> Kallithea (which is what powers BullCodes) is free software, meaning
> anyone is free to see how it works and change it and run their own
> instance and share changes.
> 
>     <URL:http://kallithea-scm.org/>

There seems to be much documentation on how to set up Kallithea as a 
server,
but I've been unable to find anything resembling a user (i.e. someone 
who
wants to keep a project hosted on bull.code) 'howto' with regard to
bull.code.  Any suggestions?

From ben+python at benfinney.id.au  Wed Apr 22 21:22:24 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Thu, 23 Apr 2015 05:22:24 +1000
Subject: [Tutor] Pun panic
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
 <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
 <85lhhlm5a1.fsf_-_@benfinney.id.au> <mh7gne$lff$1@ger.gmane.org>
 <85r3rcliz8.fsf@benfinney.id.au>
 <1782039505.901202.1429693431007.JavaMail.yahoo@mail.yahoo.com>
 <85mw20l4k0.fsf@benfinney.id.au>
 <819536b8284f6656b4894d550c0e21e8@sonic.net>
Message-ID: <85egncklxr.fsf@benfinney.id.au>

Alex Kleider <akleider at sonic.net> writes:

> On 2015-04-22 05:40, Ben Finney wrote:
> >     <URL:http://mako.cc/writing/hill-free_tools.html>
> >
> > Kallithea (which is what powers BullCodes) is free software, meaning
> > anyone is free to see how it works and change it and run their own
> > instance and share changes.
> >
> >     <URL:http://kallithea-scm.org/>
>
> [?] I've been unable to find anything resembling a user (i.e. someone
> who wants to keep a project hosted on bull.code) 'howto' with regard
> to bull.code. Any suggestions?

I don't think BullCodes has a pointer to it yet, but: Kallithea's
documentation contains a ?General Kallithea usage? section
<URL:https://docs.kallithea-scm.org/en/latest/usage/general.html>, is
that what you're looking for?

-- 
 \       ?I have always wished for my computer to be as easy to use as |
  `\       my telephone; my wish has come true because I can no longer |
_o__)          figure out how to use my telephone.? ?Bjarne Stroustrup |
Ben Finney


From fomcl at yahoo.com  Wed Apr 22 22:55:01 2015
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Wed, 22 Apr 2015 20:55:01 +0000 (UTC)
Subject: [Tutor] Pun panic
In-Reply-To: <85mw20l4k0.fsf@benfinney.id.au>
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
 <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
 <85lhhlm5a1.fsf_-_@benfinney.id.au> <mh7gne$lff$1@ger.gmane.org>
 <85r3rcliz8.fsf@benfinney.id.au>
 <1782039505.901202.1429693431007.JavaMail.yahoo@mail.yahoo.com>
 <85mw20l4k0.fsf@benfinney.id.au>
Message-ID: <1198498885.1157677.1429736101932.JavaMail.yahoo@mail.yahoo.com>





----- Original Message -----
> From: Ben Finney <ben+python at benfinney.id.au>
> To: tutor at python.org
> Cc: 
> Sent: Wednesday, April 22, 2015 2:40 PM
> Subject: Re: [Tutor] Pun panic
> 
> Albert-Jan Roskam <fomcl at yahoo.com.dmarc.invalid> writes:
> 
>>  ----- Original Message -----
>>  > From: Ben Finney <ben+python at benfinney.id.au>
>>  > You'll need a working implementation first. Put it on BullCodes
>>  > <URL:https://bull.codes/> for bonus Python-based free-software
>>  > repository hosting points!
>> 
>>  Is bull.codes better than Github or Bitbucket?
> 
> Yes, because those are not free software.
> 
>     <URL:http://mako.cc/writing/hill-free_tools.html>
> 
> Kallithea (which is what powers BullCodes) is free software, meaning
> anyone is free to see how it works and change it and run their own
> instance and share changes.
> 
>     <URL:http://kallithea-scm.org/>



Cool, though it appears to be just starting. We use Gitbucket (with a G): https://github.com/takezoe/gitbucket.
It's a Github clone, very easy to install (trivial), written in Scala.

From akleider at sonic.net  Thu Apr 23 03:29:37 2015
From: akleider at sonic.net (Alex Kleider)
Date: Wed, 22 Apr 2015 18:29:37 -0700
Subject: [Tutor] Pun panic
In-Reply-To: <85egncklxr.fsf@benfinney.id.au>
References: <CALRAYNW5bJX-g-RXcdeEvdu8ZJh0TWbK=1mgDT0s-p1oXZtuMw@mail.gmail.com>
 <mh51fa$o4j$1@ger.gmane.org> <mh52o0$d4h$1@ger.gmane.org>
 <alpine.LNX.2.00.1504210657350.1418@dagger.wonderfrog.net>
 <85lhhlm5a1.fsf_-_@benfinney.id.au> <mh7gne$lff$1@ger.gmane.org>
 <85r3rcliz8.fsf@benfinney.id.au>
 <1782039505.901202.1429693431007.JavaMail.yahoo@mail.yahoo.com>
 <85mw20l4k0.fsf@benfinney.id.au>
 <819536b8284f6656b4894d550c0e21e8@sonic.net>
 <85egncklxr.fsf@benfinney.id.au>
Message-ID: <862a36f579f265aa06dd199e3f80cd31@sonic.net>

On 2015-04-22 12:22, Ben Finney wrote:
> Alex Kleider <akleider at sonic.net> writes:
> 
>> On 2015-04-22 05:40, Ben Finney wrote:
>> >     <URL:http://mako.cc/writing/hill-free_tools.html>
>> >
>> > Kallithea (which is what powers BullCodes) is free software, meaning
>> > anyone is free to see how it works and change it and run their own
>> > instance and share changes.
>> >
>> >     <URL:http://kallithea-scm.org/>
>> 
>> [?] I've been unable to find anything resembling a user (i.e. someone
>> who wants to keep a project hosted on bull.code) 'howto' with regard
>> to bull.code. Any suggestions?
> 
> I don't think BullCodes has a pointer to it yet, but: Kallithea's
> documentation contains a ?General Kallithea usage? section
> <URL:https://docs.kallithea-scm.org/en/latest/usage/general.html>, is
> that what you're looking for?

I already looked through that page and indeed perhaps the information is 
there
but not in a way that I can understand.
No where can I find what steps to take to push a git repository that I 
have on my lap top to bullcode.
But perhaps this is the wrong venue since it isn't Python related.  
Sorry.


From cybervigilante at gmail.com  Thu Apr 23 07:18:31 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Wed, 22 Apr 2015 22:18:31 -0700
Subject: [Tutor] name shortening in a csv module output
Message-ID: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>

I'm trying the csv module. It all went well until I tried shortening a long
first name I put in just to exercise things. It didn't shorten. And I also
got weird first characters on the header line. What went wrong?

import csv
allcsv = []
with open('data.txt') as csvfile:
    readCSV = csv.reader(csvfile, delimiter='|')
    topline = next(readCSV)
    topline[0] = topline[0].replace('_', ' ').title()
    topline[1] = topline[1].replace('_', ' ').title()
    print("{0:<20s} {1:<20s}".format(topline[0], topline[1]))
    print('==================================')
    for line in readCSV:
        if len(line[0]) > 40:  # problem here - didn't shorten
            line[0] = line[0][:40]
        print("{0:<20s} {1:<20s}".format(line[0], line[1]))

Original file lines:

first_name|last_name|email|city|state or region|address|zip
Stewartrewqrhjeiwqhreqwhreowpqhrueqwphruepqhruepqwhruepwhqupr|Dorsey|nec.malesuada at Quisqueporttitoreros.com|Cariboo
Regional District|BC|P.O. Box 292, 8945 Nulla Avenue|5945
Madonna|Sosa|senectus.et at eget.ca|Belford Roxo|Rio de Janeiro|P.O. Box 538,
4484 Sem Avenue|81833
Duncan|Hutchinson|Donec.vitae at Integer.co.uk|Dublin|Leinster|Ap #847-2344
Feugiat. St.|9222
...

My result:

???First Name        Last Name           # odd characters on header line
==================================
Stewartrewqrhjeiwqhreqwhreowpqhrueqwphru Dorsey
Madonna              Sosa
Duncan               Hutchinson
...




-- 
Jim

No comment

From __peter__ at web.de  Thu Apr 23 10:42:40 2015
From: __peter__ at web.de (Peter Otten)
Date: Thu, 23 Apr 2015 10:42:40 +0200
Subject: [Tutor] name shortening in a csv module output
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
Message-ID: <mhaba6$gvd$1@ger.gmane.org>

Jim Mooney wrote:

> I'm trying the csv module. It all went well until I tried shortening a
> long first name I put in just to exercise things. It didn't shorten. 


> Original file lines:

> Stewartrewqrhjeiwqhreqwhreowpqhrueqwphruepqhruepqwhruepwhqupr|Dorsey|
nec.malesuada at Quisqueporttitoreros.com|Cariboo

> My result:

> Stewartrewqrhjeiwqhreqwhreowpqhrueqwphru Dorsey
 

It did shorten:

>>> len("Stewartrewqrhjeiwqhreqwhreowpqhrueqwphruepqhruepqwhruepwhqupr")
61
>>> len("Stewartrewqrhjeiwqhreqwhreowpqhrueqwphru")
40

>         if len(line[0]) > 40:  # problem here - didn't shorten
>             line[0] = line[0][:40]
>         print("{0:<20s} {1:<20s}".format(line[0], line[1]))

You have to make up your mind if you want to shortend to 40 or 20 chars.

> And I also got weird first characters on the header line. What went wrong?

> Original file lines:
> 
> first_name|last_name|email|city|state or region|address|zip
...

> My result:
> 
> ???First Name        Last Name           # odd characters on header line
...

???

is the UTF-8 BOM (byte order mark) interpreted as Latin 1.

If the input is UTF-8 you can get rid of the BOM with

with open("data.txt", encoding="utf-8-sig") as csvfile:
    ...



From cybervigilante at gmail.com  Thu Apr 23 12:37:11 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Thu, 23 Apr 2015 03:37:11 -0700
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <mhaba6$gvd$1@ger.gmane.org>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
Message-ID: <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>

..

> ???
>
> is the UTF-8 BOM (byte order mark) interpreted as Latin 1.
>
> If the input is UTF-8 you can get rid of the BOM with
>
> with open("data.txt", encoding="utf-8-sig") as csvfile:
>

Peter Otten

I caught the bad arithmetic on name length, but where is the byte order
mark coming from? My first line is plain English so far as I can see - no
umlauts or foreign characters.
first_name|last_name|email|city|state or region|address|zip

Is this an artifact of csv module output, or is it the data from
generatedata.com, which looks global? More likely it means I have to figure
out unicode ;'(

From __peter__ at web.de  Thu Apr 23 14:05:31 2015
From: __peter__ at web.de (Peter Otten)
Date: Thu, 23 Apr 2015 14:05:31 +0200
Subject: [Tutor] name shortening in a csv module output
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
Message-ID: <mhan6d$nuv$1@ger.gmane.org>

Jim Mooney wrote:

> ..
> 
>> ???
>>
>> is the UTF-8 BOM (byte order mark) interpreted as Latin 1.
>>
>> If the input is UTF-8 you can get rid of the BOM with
>>
>> with open("data.txt", encoding="utf-8-sig") as csvfile:
>>
> 
> Peter Otten
> 
> I caught the bad arithmetic on name length, but where is the byte order
> mark coming from? 

Did you touch the data with an editor? That might be the culprit.

> My first line is plain English so far as I can see - no
> umlauts or foreign characters.
> first_name|last_name|email|city|state or region|address|zip
> 
> Is this an artifact of csv module output, or is it the data from
> generatedata.com, which looks global? More likely it means I have to
> figure out unicode ;'(



From d at davea.name  Thu Apr 23 16:29:42 2015
From: d at davea.name (Dave Angel)
Date: Thu, 23 Apr 2015 10:29:42 -0400
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
Message-ID: <553901D6.90006@davea.name>

On 04/23/2015 06:37 AM, Jim Mooney wrote:
> ..
>
>> ???
>>
>> is the UTF-8 BOM (byte order mark) interpreted as Latin 1.
>>
>> If the input is UTF-8 you can get rid of the BOM with
>>
>> with open("data.txt", encoding="utf-8-sig") as csvfile:
>>
>
> Peter Otten
>
> I caught the bad arithmetic on name length, but where is the byte order
> mark coming from? My first line is plain English so far as I can see - no
> umlauts or foreign characters.
> first_name|last_name|email|city|state or region|address|zip
>
> Is this an artifact of csv module output, or is it the data from
> generatedata.com, which looks global? More likely it means I have to figure
> out unicode ;'(

A file is always stored as bytes, so if it's a text file, it is always 
an encoded file (although if it's ASCII, you tend not to think of that 
much).

So whatever program writes that file has picked an encoding, and when 
you read it you have to use the same encoding to safely read it into text.

By relying on the default when you read it, you're making an unspoken 
assumption about the encoding of the file.

There are dozens of common encodings out there, and anytime you get the 
wrong one, you're likely to mess up somewhere, unless it happens to be 
pure ASCII.

The BOM is not supposed to be used in a byte encoded file, but Notepad, 
among other programs does.  So it happens to be a good clue that the 
rest of the file is encoded in utf-8.  If that's the case, and if you 
want to strip the BOM, use utf-8-sig.

Note:  the BOM may be legal in utf-8 now, but it was originally intended 
to distinguish the UTF-32-BE from UTF-32-LE, as well as UTF-16-BE from 
UTF-16-LE.

https://docs.python.org/2/library/codecs.html#encodings-and-unicode

-- 
DaveA

From cybervigilante at gmail.com  Thu Apr 23 20:14:52 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Thu, 23 Apr 2015 11:14:52 -0700
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <553901D6.90006@davea.name>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
Message-ID: <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>

>
> By relying on the default when you read it, you're making an unspoken
> assumption about the encoding of the file.
>
> --
> DaveA


So is there any way to sniff the encoding, including the BOM (which appears
to be used or not used randomly for utf-8), so you can then use the proper
encoding, or do you wander in the wilderness? I was going to use encoding =
utf-8 as a suggested default. I noticed it got rid of the bom symbols but
left an extra blank space at the beginning of the stream. Most books leave
unicode to the very end, if they mention the BOM at all (mine is at page
977, which is still a bit off ;')

From breamoreboy at yahoo.co.uk  Thu Apr 23 23:08:05 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Thu, 23 Apr 2015 22:08:05 +0100
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
Message-ID: <mhbmvo$4md$1@ger.gmane.org>

On 23/04/2015 19:14, Jim Mooney wrote:
>>
>> By relying on the default when you read it, you're making an unspoken
>> assumption about the encoding of the file.
>>
>> --
>> DaveA
>
>
> So is there any way to sniff the encoding, including the BOM (which appears
> to be used or not used randomly for utf-8), so you can then use the proper
> encoding, or do you wander in the wilderness? I was going to use encoding =
> utf-8 as a suggested default. I noticed it got rid of the bom symbols but
> left an extra blank space at the beginning of the stream. Most books leave
> unicode to the very end, if they mention the BOM at all (mine is at page
> 977, which is still a bit off ;')
>

I'm hardly an expert in the encoding field but I've heard this 
https://pypi.python.org/pypi/chardet is highly recommended.

Slight aside, why a BOM, all I ever think of is Inspector Clouseau? :)

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From alan.gauld at btinternet.com  Thu Apr 23 23:09:50 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 23 Apr 2015 22:09:50 +0100
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
Message-ID: <mhbn2s$6ck$1@ger.gmane.org>

On 23/04/15 19:14, Jim Mooney wrote:
>>
>> By relying on the default when you read it, you're making an unspoken
>> assumption about the encoding of the file.

>
> So is there any way to sniff the encoding, including the BOM (which appears
> to be used or not used randomly for utf-8), so you can then use the proper
> encoding, or do you wander in the wilderness?

Pretty much guesswork.

The move from plain old ASCII to Unicode (and others) has made the 
handling of text much more like binary. You have to know the binary 
format/encoding to know how to decode binary data. Its the same with 
text, if you don't know what produced it, and in what format, then you 
have to guess.

There are some things you can do to check your results (such as try 
spell checking the results) and you can try checking the characters 
against the Unicode mappings to see if the sequences look sane.
(for example a lot of mixed alphabets - like arabic, greek and
latin - suggests you guessed wrong!) But none of it is really
reliable.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From davea at davea.name  Thu Apr 23 23:30:43 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 23 Apr 2015 17:30:43 -0400
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
Message-ID: <55396483.5080803@davea.name>

On 04/23/2015 02:14 PM, Jim Mooney wrote:
>>
>> By relying on the default when you read it, you're making an unspoken
>> assumption about the encoding of the file.
>>
>> --
>> DaveA
>
>
> So is there any way to sniff the encoding, including the BOM (which appears
> to be used or not used randomly for utf-8), so you can then use the proper
> encoding, or do you wander in the wilderness? I was going to use encoding =
> utf-8 as a suggested default. I noticed it got rid of the bom symbols but
> left an extra blank space at the beginning of the stream. Most books leave
> unicode to the very end, if they mention the BOM at all (mine is at page
> 977, which is still a bit off ;')


That's not a regular blank,  See the link I mentioned before, and the 
following sentence:

""" Unfortunately the character U+FEFF had a second purpose as a ZERO 
WIDTH NO-BREAK SPACE: a character that has no width and doesn?t allow a 
word to be split. It can e.g. be used to give hints to a ligature 
algorithm. """

To automatically get rid of that BOM character when reading a file, you 
use utf-8-sig, rather than utf-8.  And on writing, since you probably 
don't want it, use utf-8.

As for guessing what encoding was used, the best approach is to ask the 
person/program that wrote the file.  Or read the specs.  And once you 
figure it out, fix the specs.

With a short sample, you're unlikely to guess right.  That's because 
ASCII looks the same in all the byte-encoded formats.  (Not in the 
various *16* and *32* formats, as they use 2 bytes or 4 bytes each)  If 
you encounter one of those, you'll probably see lots of null bytes mixed 
in a consistent pattern.


Consider the 'file' command in Linux.  I don't know of any Windows 
equivalent.

If you want to write your own utility, perhaps to scan hundreds of 
files, consider:

   http://pypi.python.org/pypi/chardet
   http://linux.die.net/man/3/libmagic
   https://github.com/ahupp/python-magic

-- 
-- 
DaveA

From davea at davea.name  Thu Apr 23 23:40:34 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 23 Apr 2015 17:40:34 -0400
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <mhbmvo$4md$1@ger.gmane.org>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbmvo$4md$1@ger.gmane.org>
Message-ID: <553966D2.8070809@davea.name>

On 04/23/2015 05:08 PM, Mark Lawrence wrote:
>
> Slight aside, why a BOM, all I ever think of is Inspector Clouseau? :)
>

As I recall, it stands for "Byte Order Mark".  Applicable only to 
multi-byte storage formats  (eg. UTF-16), it lets the reader decide 
which of the formats were used.

For example, a file that reads

    fe ff 41 00 42 00

might be a big-endian version of UTF-16

while
    ff fe 00 41 00 42

might be the little-endian version of the same data.

I probably have it all inside out and backwards, but that's the general 
idea.  If the BOM appears backwards, you switch between BE and LE and 
the data will make sense.


The same concept was used many years ago in two places I know of. 
Binary files representing faxes had "II" or "MM" at the beginning.

But the UCSD-P system program format used a number (I think it was 0001) 
which would decode wrong if you were on the wrong processor type.  The 
idea was that instead of coding an explicit check, you just looked at 
one piece of data, and if it was wrong, you had to swap all the 
byte-pairs.  That way if you read the file on the same machine, no work 
was needed at all.

Seems to me the Java bytecode does something similar, but I don't know. 
  All of these are from memory, and subject to mis-remembering.


-- 
DaveA

From alan.gauld at btinternet.com  Fri Apr 24 01:33:57 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 24 Apr 2015 00:33:57 +0100
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>	<mhaba6$gvd$1@ger.gmane.org>	<CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>	<553901D6.90006@davea.name>	<CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>	<mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
Message-ID: <55398165.3050401@btinternet.com>

On 24/04/15 00:15, Jim Mooney wrote:
> Pretty much guesswork.
> Alan Gauld
> -- 
> This all sounds suspiciously like the old browser wars

Its more about history. Early text encodings all worked in a single byte 
which is
limited to 256 patterns. That's simply not enough to cover all the 
alphabets
around. So people developed their own encodings for every computer 
platform,
printer, county and combinations thereof. Unicode is an attempt to get away
from that, but the historical junk is still out there. And unicode is 
not yet
the de-facto standard.

Now the simple thing to do would be just have one enormous character
set that covers everything. That's Unicode 32 bit encoding. The snag is
that it takes 4 bytes for every character, which is a lot of 
space/bandwidth.
So more efficient encodings were introduced such as Unicode "16 bit" and
"8 bit", aka utf-8.

UTF-8 is becoming a standard but it has the complication that its a 
variable
width standard where a character can be anything from a single byte up
to 4 bytes long. The "rarer" the character the longer its encoding. And
unfortunately the nature of the coding is such that it looks a lot like
other historical encodings, especially some of the Latin ones. So you can
get something almost sane out of a text by decoding it as utf8 but not
quite totally sane. And it maybe some time into your usage before you
realise you are actually using the wrong code!

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


From steve at pearwood.info  Fri Apr 24 02:09:54 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Apr 2015 10:09:54 +1000
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
Message-ID: <20150424000953.GQ5663@ando.pearwood.info>

On Wed, Apr 22, 2015 at 10:18:31PM -0700, Jim Mooney wrote:

> My result:
> 
> ???First Name        Last Name           # odd characters on header line

Any time you see "odd characters" in text like that, you should 
immediately think "encoding problem".

These odd characters are normally called mojibake, a Japanese term, or 
sometimes gremlins. Mojibake occurs when your text file was written in 
one encoding but then read back using another, e.g.:

* file was written using a Windows code page, but read back on a 
  different PC using a different code page (say, Greek then Russian);

* file was written on a classic Macintosh (pre-OS X), then read on a 
  DOS or Windows machine;

* file was written on a mainframe that uses ASCII and transferred to
  a mainframe that uses EBCDIC;

* file was written using an editor that defaults to one encoding, 
  and read back using an editor that defaults to a different encoding;

* HTML web page was saved using one encoding, but not declared (or
  declared wrongly) and the browser defaults to a different encoding.


Sadly, this problem is hard to solve because text files can't, in 
general, contain metadata that tells you how the text is stored. We're 
reduced to conventions, hints, and guesses. Given that, the fact that 
there is so little mojibake in the world compared to how much there 
could be is astonishing.


In your case, those specific three characters ??? found at the start of 
a text file indicates that the text file was saved by Notepad on 
Windows. For no good reason (although I'm sure it seemed like a good 
idea at the time, if they were smoking crack at the time), Notepad 
sometimes puts a UTF-8 signature at the start of text files. Actually 
Notepad tries to be way too clever but isn't clever enough:

http://en.wikipedia.org/wiki/Bush_hid_the_facts
?
This UTF-8 signature is sometimes called a "Byte Order Mark", or BOM, 
which is a misnomer. The solution is to use the utf-8-sig encoding 
instead of utf-8.



-- 
Steve

From steve at pearwood.info  Fri Apr 24 03:29:38 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Apr 2015 11:29:38 +1000
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <mhbmvo$4md$1@ger.gmane.org>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbmvo$4md$1@ger.gmane.org>
Message-ID: <20150424012938.GR5663@ando.pearwood.info>

On Thu, Apr 23, 2015 at 10:08:05PM +0100, Mark Lawrence wrote:

> Slight aside, why a BOM, all I ever think of is Inspector Clouseau? :)

:-)

I'm not sure if you mean that as an serious question or not. 

BOM stands for Byte Order Mark, and it if needed for UTF-16 and UTF-32 
encodings because there is some ambiguity due to hardware differences.

UTF-16 uses two byte "code units", that is, each character is 
represented by two bytes (or four, but we can ignore that). Similarly, 
UTF-32 uses four byte code units. The problem is, different platforms 
link multiple bytes in opposite order: "big-endian" and "little-endian". 
(In the Bad Old Days, there were "middle-endian" platforms too, and you 
really don't want to know about them.) For example, the two-byte 
quantity O1FE (in hex) might have:

(1) the 01 byte at address 100 and the FE byte at address 101 
    (big end first)

(2) the 01 byte at address 101 and the FE byte at address 100
    (little end first)


We always write the two bytes as 01FE in hexadecimal notation, with the 
"little end" (units) on the right, just as we do with decimals: 

01FE = E units + F sixteens + 1 sixteen-squares + 0 sixteen-cubes 

is the same as 510 in decimal:

510 = 0 units + 1 ten + 5 ten-squares

but in computer memory those two bytes could be stored either big-end 
first:

    01 has the lower address
    FE has the higher address

or little-end first:

    FE has the lower address
    01 has the higher address


So when you read a text file, and you see two bytes 01FE, unless you 
know whether that came from a big-endian system or a little-endian 
system, you don't know how to interpret it:

- If both the sender and the receiver are big-endian, or little-endian, 
  then two bytes 01 followed by FE represent 01FE or 510 in decimal, 
  which is LATIN CAPITAL LETTER O WITH STROKE AND ACUTE in UTF-16.

- If the sender and the receiver are opposite endians (one big-, 
  the other little-, it doesn't matter which) then the two bytes 01 
  followed by FE will be seen as FE01 (65025 in decimal) which is 
  VARIATION SELECTOR-2 in UTF-16.

I've deliberately used the terms "sender" and "receiver", because this 
problem is fundamental to networking too. Whenever you transfer data 
from a Motorola based platform to an Intel based platform, the byte 
order has to be swapped like this. If it's not swapped, the data looks 
weird. (TIFF files also have to take endian issues into account.)

UTF-16 and UTF-32 solve this problem by putting a Byte Order Mark at the 
start of the file. The BOM is two bytes in the case of UTF-16 (a single 
code-unit):

py> ''.encode('utf-16')
b'\xff\xfe'

So when you read a UTF-16 file back, if it starts with two bytes FFFE 
(in hex), you can continue. If it starts with FEFF, then the bytes have 
been reversed.

If you treat the file as Latin-1 (one of the many versions of "extended 
ASCII"), then you will see the BOM as either:

??  # byte order matches

??  # byte order doesn't match


Normally you don't need to care about any of this! The encoding handles 
all the gory details. You just pick the right encoding:

- UTF-16 if the file will have a BOM;

- UTF-16BE if it is big-endian, and doesn't have a BOM;

- UTF-16LE if it is little-endian, and doesn't have a BOM;

and the encoding deals with the BOM.




-- 
Steve

From steve at pearwood.info  Fri Apr 24 03:55:59 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Apr 2015 11:55:59 +1000
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <553966D2.8070809@davea.name>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbmvo$4md$1@ger.gmane.org> <553966D2.8070809@davea.name>
Message-ID: <20150424015558.GS5663@ando.pearwood.info>

On Thu, Apr 23, 2015 at 05:40:34PM -0400, Dave Angel wrote:
> On 04/23/2015 05:08 PM, Mark Lawrence wrote:
> >
> >Slight aside, why a BOM, all I ever think of is Inspector Clouseau? :)
> >
> 
> As I recall, it stands for "Byte Order Mark".  Applicable only to 
> multi-byte storage formats  (eg. UTF-16), it lets the reader decide 
> which of the formats were used.
> 
> For example, a file that reads
> 
>    fe ff 41 00 42 00
> 
> might be a big-endian version of UTF-16
> 
> while
>    ff fe 00 41 00 42
> 
> might be the little-endian version of the same data.

Almost :-)

You have the string ")*", two characters. In ASCII, Latin-1, Mac-Roman, 
UTF-8, and many other encodings, that is represented by two code points. 
I'm going to use "U+ hex digits" as the symbol for code points, to 
distinguish them from raw bytes which won't use the U+ prefix.

string ")*" gives code points U+41 U+42

They get written out to a single byte each, and so we get

41 42

as the sequence of bytes (still written in hex).

In UTF-16, those two characters are represented by the same two code 
points, *but* the "code unit" is two bytes rather than one: 

U+0041 U+0042

with leading zeroes included. Each code unit gets written out as a 
two-byte quantity:

On little-endian systems like Intel hardware: 4100 4200

On big-endian systems like Motorola hardware: 0041 0042

Insert the BOM, which is always code point U+FEFF:

On little-endian systems: FFFE 4100 4200

On big-endian systems: FEFF 0041 0042

If you take that file and read it back as Latin-1, you get:

little-endian: ??A\0B\0
big-endian: ??\0A\0B

Notice the \0 nulls? Your editor might complain that the file is a 
binary file, and refuse to open it, unless you tell the editor it is 
UTF-16.


> The same concept was used many years ago in two places I know of. 
> Binary files representing faxes had "II" or "MM" at the beginning.

Yes, TIFF files use a similar scheme. You get them starting with a 
signature TIFF or FFTI, I believe.


-- 
Steve

From steve at pearwood.info  Fri Apr 24 04:46:20 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Apr 2015 12:46:20 +1000
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <55398165.3050401@btinternet.com>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
 <55398165.3050401@btinternet.com>
Message-ID: <20150424024619.GT5663@ando.pearwood.info>

On Fri, Apr 24, 2015 at 12:33:57AM +0100, Alan Gauld wrote:
> On 24/04/15 00:15, Jim Mooney wrote:
> >Pretty much guesswork.
> >Alan Gauld
> >-- 
> >This all sounds suspiciously like the old browser wars
> 
> Its more about history. Early text encodings all worked in a single byte 
> which is
> limited to 256 patterns.

Oh it's much more complicated than that!

The first broadly available standard encoding was ASCII, which was 
*seven bits*, not even a full byte. It was seven bits so that there was 
an extra bit available for error correction when sending over telex or 
some such thing.

(There were other encodings older than ASCII, like EBCDIC, which was 
used on IBM mainframes and is either 7 or 8 bits.)

With seven bits, you can only have 127 characters. About 30 odd are used 
for control characters (which used to be important, now only two or 
three of them are still commonly used, but we're stuck with them 
forever), so ASCII is greatly impoverished, even for American English. 
(E.g. there is no cent symbol.)

Hence the 1970s through 90s saw an explosion of "code pages" for Windows 
systems, national standards which extended ASCII to use a full 8 bits 
(plus a few 16-bit and variable-bit standards as well). Fortunately 
people rarely swapped documents from one platform to another.

Then, in the late 1990s, Internet access started becoming common, and 
what do people do on the Internet? They exchange files. Chaos and 
confusion everywhere...


> That's simply not enough to cover all the 
> alphabets
> around. So people developed their own encodings for every computer 
> platform,
> printer, county and combinations thereof. Unicode is an attempt to get away
> from that, but the historical junk is still out there. And unicode is 
> not yet
> the de-facto standard.

Not quite. Unicode is an actual real standard, and pretty much everyone 
agrees that it is the only reasonable choice[1] as a standard. It is 
quite close to being a standard in practice as well as on paper: Unicode 
is more or less the language of the Internet, something like 85% of web 
pages now use UTF-8, Linux and Mac desktops use UTF-8, Windows provides 
optional Unicode interfaces for their programming APIs, most modern 
languages (with the exception of PHP, what a surprise) provide at least 
moderate Unicode support.

Sadly though you are right that there are still historical documents to 
deal with and (mostly Windows) systems which even today still default to 
using legacy encodings rather than Unicode. We'll be dealing with legacy 
encodings for decades, especially since East Asian countries lag behind 
the West for Unicode adoption, but Unicode has won.


> Now the simple thing to do would be just have one enormous character
> set that covers everything. That's Unicode 32 bit encoding.

No it isn't :-)

The character set and the encoding are *not the same*. We could have a 
two-character set with a 32-bit encoding, if we were nuts:

Two characters only: A and B

A encodes as four bytes 00 00 00 00
B encodes as four bytes FF FF FF FF

and every other combination of bytes is an error.

The set of characters provided by Unicode is the same regardless of how 
those characters are encoded to and from bytes.

The official standard is the "Universal Character Set", or UCS, which 
supports 1114112 different "code points", numbered from U+0000 to 
U+10FFFF. Each code point represents:

- a character (letter, digit, symbol, etc.)
- control character
- private-use characters
- reserved for future use
- non-characters (e.g. BOM, variation selectors, surrogates)
- combining accents

etc. Unicode can be considered the same as UCS plus a bunch of other 
stuff, such as rules for sorting.

Notice that UCS and Unicode deliberately use much less than the full 
4294967296 possible values of a 32-bit quantity. You can fit Unicode in 
21 bits.

Historically, the UCS started at 16 bits, it may have reserved the full 
32 bits, but it is now guaranteed to use no more than 21 bits U+10FFFF 
will be the highest code point forever.


> The snag is
> that it takes 4 bytes for every character, which is a lot of 
> space/bandwidth.
> So more efficient encodings were introduced such as Unicode "16 bit" and
> "8 bit", aka utf-8.

Historically, the Universal Character Set and Unicode originally was 
only 16 bit, so the first UCS encoding was UCS-2, which uses two bytes 
for every code point. But they soon realised that they needed more than 
65536 code points, and UCS-2 is now obsolute.

The current version of Unicode and UCS uses 21 bits, and 
guaranteed that there will be no future expansions. They include a 
bunch of encodings:

UCS-4 uses a full 32-bits per code point; it is defined in the UCS 
standard.

UTF-32 does the same, except in the Unicode standard. They are 
effectively identical, just different names because they live in 
different standards.

UTF-16 is a variable-width encoding, using either 2 bytes or 4. It is 
effectively an extension to the obsolete UCS-2.

UTF-8 is a variable-width encoding, using 1, 2, 3, or 4 bytes. The 
mechanism works for up to six bytes, but the standard guarantees that it 
will never exceed 4 bytes.

UTF-7 is a "seven-bit clean" version, for systems which cannot deal with 
text data with the high-bit set.

There are a few others in the various standards, but nobody uses them 
:-)



> UTF-8 is becoming a standard but it has the complication that its a 
> variable
> width standard where a character can be anything from a single byte up
> to 4 bytes long. The "rarer" the character the longer its encoding. And
> unfortunately the nature of the coding is such that it looks a lot like
> other historical encodings, especially some of the Latin ones. So you can
> get something almost sane out of a text by decoding it as utf8 but not
> quite totally sane. And it maybe some time into your usage before you
> realise you are actually using the wrong code!

That's by design! If you use nothing but ASCII characters, then UTF-8 
and ASCII are identical.

If you save a text file "Hello World!" using any of the other UTF 
encodings (UTF-16, -32 in particular), you will get something which an 
old, dumb non-Unicode aware application cannot deal with. It will treat 
it as a binary file, because it contains lots of zero bytes. C programs 
will choke on it.

But with UTF-8, so long as you limit yourself to only ASCII characters, 
old ASCII programs will continue to work fine. This was a very important 
requirement that allowed Unicode to become popular. Editors can ship 
defaulting to UTF-8, and so long as their users only type ASCII 
characters other non-Unicode programs won't know the difference.





[1] There are a very few people in Japan who use TRON instead, because 
TRON separates Japanese characters from their identical Chinese and 
Korean characters -- think about having a separate English A, French A 
and German A. Pretty much nobody else uses it, and precious few 
Japanese. It's not quite 100% due to Japanese nationalism, there are 
some good reasons for wanting to separate the characters, but it's 
probably 97% Japanese nationalism. The Japanese, Chinese and Korean 
governments, as well as linguists, are all in agreement that despite a 
few minor differences, the three languages share a common character set.


-- 
Steve

From cybervigilante at gmail.com  Fri Apr 24 01:15:39 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Thu, 23 Apr 2015 16:15:39 -0700
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <mhbn2s$6ck$1@ger.gmane.org>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
Message-ID: <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>

So is there any way to sniff the encoding, including the BOM (which appears
to be used or not used randomly for utf-8), so you can then use the proper
encoding, or do you wander in the wilderness?

Pretty much guesswork.
>

Alan Gauld
-- 
This all sounds suspiciously like the old browser wars I suffered while
webmastering. I'd almost think Microsoft had a hand in it ;')  If utf-8 can
handle a million characters, why isn't it just the standard? I doubt we'd
need more unless the Martians land.

Since I am reading opinions that the BOM doesn't even belong in utf-8, can
I assume just using utf-8-sig as my default encoding, even on a non-BOM
file, would do no harm?

Jim

From cybervigilante at gmail.com  Fri Apr 24 04:37:56 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Thu, 23 Apr 2015 19:37:56 -0700
Subject: [Tutor] Spongebob Pythonpants
Message-ID: <CALRAYNWPB_W7bReHHH_gAsHKdsBwJaOie7qPJ_QD0g56GetQ6w@mail.gmail.com>

I was depressed at the thought of learning unicode, then discovered Python
was fun again since I can easily print any ascii art from
http://www.chris.com/ascii/  with a multiline print, so long as I replace
any backslash with two of them. Spongebob Squarepants was, of course, the
obvious first choice. The heck with Tkinter. (Bob is coming out a bit thin
in my gmail but looks fine in the REPL.)

print('''
      .--..--..--..--..--..--.
    .' \\  (`._   (_)     _   \\
  .'    |  '._)         (_)  |
  \\ _.')\\      .----..---.   /
  |(_.'  |    /    .-\\-.  \\  |
  \\     0|    |   ( O| O) | o|
   |  _  |  .--.____.'._.-.  |
   \\ (_) | o         -` .-`  |
    |    \\   |`-._ _ _ _ _\\ /
    \\    |   |  `. |_||_|   |
    | o  |    \\_      \\     |     -.   .-.
    |.-.  \\     `--..-'   O |     `.`-' .'
  _.'  .' |     `-.-'      /-.__   ' .-'
.' `-.` '.|='=.='=.='=.='=|._/_ `-'.'
`-._  `.  |________/\\_____|    `-.'
   .'   ).| '=' '='\\/ '=' |
   `._.`  '---------------'
           //___\\   //___\\
             ||       ||
    LGB      ||_.-.   ||_.-.
            (_.--__) (_.--__)''')


*** Remote Interpreter Reinitialized  ***
>>>

      .--..--..--..--..--..--.
    .' \  (`._   (_)     _   \
  .'    |  '._)         (_)  |
  \ _.')\      .----..---.   /
  |(_.'  |    /    .-\-.  \  |
  \     0|    |   ( O| O) | o|
   |  _  |  .--.____.'._.-.  |
   \ (_) | o         -` .-`  |
    |    \   |`-._ _ _ _ _\ /
    \    |   |  `. |_||_|   |
    | o  |    \_      \     |     -.   .-.
    |.-.  \     `--..-'   O |     `.`-' .'
  _.'  .' |     `-.-'      /-.__   ' .-'
.' `-.` '.|='=.='=.='=.='=|._/_ `-'.'
`-._  `.  |________/\_____|    `-.'
   .'   ).| '=' '='\/ '=' |
   `._.`  '---------------'
           //___\   //___\
             ||       ||
    LGB      ||_.-.   ||_.-.
            (_.--__) (_.--__)
>>>


-- 
Jim

No comment

From alan.gauld at btinternet.com  Fri Apr 24 10:54:06 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 24 Apr 2015 09:54:06 +0100
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <20150424024619.GT5663@ando.pearwood.info>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
 <55398165.3050401@btinternet.com> <20150424024619.GT5663@ando.pearwood.info>
Message-ID: <mhd0bc$iu8$1@ger.gmane.org>

On 24/04/15 03:46, Steven D'Aprano wrote:

>> Early text encodings all worked in a single byte
>> which is limited to 256 patterns.
>
> Oh it's much more complicated than that!

Note I said *in* a single byte, ie they were all 8 bits or less.

> *seven bits*, not even a full byte. It was seven bits so that there was
> an extra bit available for error correction when sending over telex or
> some such thing.

Telex actually uses (its still in active use) its own alphabet
(ITA-2) which was a 5 bit pattern based on the old Murray code.
This meant there were 32 patterns, not enough for letters and
numbers or other symbols so there were two sets of meanings to
each pattern and a shift pattern to switch between them (which is
why we have SHIFT keys on modern keyboards). Even so, lower-case
letters were considered a luxury and didn't exist!

It also had separate characters for line-feed and carriage-return.
The keys for these were arranged vertically above each other
about where the Enter key on the number keypad is today. The
operator did a newline by stroking down over both keys sequentially.
That's why the enter key is long and thin today.(although I
don't know why the plus is that shape!) - I learned to type
on a Telex machine! :-)

> (There were other encodings older than ASCII, like EBCDIC, which was
> used on IBM mainframes and is either 7 or 8 bits.)

EBCDIC and ASCII both debuted in 1963. EBCDIC is 8 bit but
has terrible sorting semantics. (I briefly programmed on
OS/390 for the millenium bug panic :-( )

>> Now the simple thing to do would be just have one enormous character
>> set that covers everything. That's Unicode 32 bit encoding.
>
> No it isn't :-)

OK, I tried to simplify and confused the coding with the character set.
You are of course correct! :-)

> Historically, the UCS started at 16 bits, it may have reserved the full
> 32 bits, but it is now guaranteed to use no more than 21 bits U+10FFFF
> will be the highest code point forever.

Ah, this is new to me. I assumed they could use the full 32 bits.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From steve at pearwood.info  Fri Apr 24 12:08:00 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Apr 2015 20:08:00 +1000
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
Message-ID: <20150424100800.GV5663@ando.pearwood.info>

The quoting seems to be all mangled here, so please excuse me if I 
misattribute quotes to the wrong person:

On Thu, Apr 23, 2015 at 04:15:39PM -0700, Jim Mooney wrote:

> So is there any way to sniff the encoding, including the BOM (which appears
> to be used or not used randomly for utf-8), so you can then use the proper
> encoding, or do you wander in the wilderness?
> 
> Pretty much guesswork.

There is no foolproof way to guess encodings, since you might happen to 
have text which *looks* like it starts with a BOM but is actually not. 
E.g. if you happen to have text which starts with ?? then it might be 
identified as a BOM even though the author intended it to actually be ?? 
in the Latin-1 encoding.

This is no different from any other file format. All files are made from 
bytes, and there is no such thing as "JPEG bytes" and "TXT bytes" and 
"MP3 bytes", they're all the same bytes. In principle, you could have a 
file which was a valid JPG, ZIP and WAV file *at the same time* 
(although not likely by chance). And if not those specific three, then 
pick some other combination.

*But*, while it is true that in principle you cannot guess the encoding 
of files, in practice you often can guess quite successfully. Checking 
for a BOM is easy. For example, you could use these two functions:


def guess_encoding_from_bom(filename, default='undefined'):
    with open(filename, 'rb') as f:
        sig = f.read(4)
    return bom2enc(sig, default)

# Untested.
def bom2enc(bom, default=None):
    if bom.startswith((b'\x00\x00\xFE\xFF', b'\xFF\xFE\x00\x00')):
        return 'utf_32'
    elif bom.startswith((b'\xFE\xFF', b'\xFF\xFE')):
        return 'utf_16'
    elif bom.startswith(b'\xEF\xBB\xBF'):
        return 'utf_8_sig'
    elif bom.startswith(b'\x2B\x2F\x76'):
        if len(bom) == 4 and bom[4] in b'\x2B\x2F\x38\x39':
            return 'utf_7'
    elif bom.startswith(b'\xF7\x64\x4C'):
        return 'utf_1'
    elif default is None:
        raise ValueError
    else:
        return default


If you have a BOM, chances are very good that the text is encoded 
correctly. If not, you can try decoding, and if it fails, try again:

for encoding in ('utf-8', 'utf-16le', 'utf-16be'):
    try:
        with open("filename", "r", encoding=encoding) as f:
            return f.read()
    except UnicodeDecodingError:
        pass
raise UnicodeDecodingError("I give up!")


You can use chardet to guess the encoding. That's a Python port of the 
algorithm used by Firefox to guess the encoding of webpages when the 
declaration is missing:

https://pypi.python.org/pypi/chardet

chardet works by statistically analysing the characters in the text and 
tries to pick an encoding that minimizes the number of gremlins.

Or you can try fixing errors after they occur:

http://blog.luminoso.com/2012/08/20/fix-unicode-mistakes-with-python/


> This all sounds suspiciously like the old browser wars I suffered while
> webmastering. I'd almost think Microsoft had a hand in it ;')  

Ha! In a way they did, because Microsoft Windows code pages are legacy 
encodings. But given that there were no alternatives back in the 1980s, 
I can't blame Microsoft for the mess in the past. (Besides, MS are one 
of the major sponsors of Unicode, so they are helping to fix the problem 
too.)

> If utf-8 can
> handle a million characters, why isn't it just the standard? I doubt we'd
> need more unless the Martians land.

UTF-8 is an encoding, not a character set. The character set tells us 
what characters we can use:

D ? ? ? ? ? ? ? ? ? ? ?

are all legal in Unicode, but not in ASCII, Latin-1, ISO-8859-7, BIG-5, 
or any of the dozens of other character sets.

The encoding tells us how to turn a character like A or ? into one or 
more bytes to be stored on disk, or transmitted over a network. In the 
non-Unicode legacy encodings, we often equate the character set with the 
encoding (or codec), e.g. we say that ASCII A *is* byte 65 (decimal) or 
41 (hex). But that's sloppy language. The ASCII character set includes 
the character A (but not ?) while the encoding tells us character A gets 
stored as byte 41 (hex).

To the best of my knowledge, Unicode is the first character set which 
allows for more than one encoding.

Anyway, Unicode is *the* single most common character set these days, 
more common than even ASCII and Latin-1. About 85% of webpages use 
UTF-8.


> Since I am reading opinions that the BOM doesn't even belong in utf-8, can
> I assume just using utf-8-sig as my default encoding, even on a non-BOM
> file, would do no harm?

Apparently so. It looks like utf_8-sig just ignores the sig if it is 
present, and uses UTF-8 whether the signature is present or not.

That surprises me.


-- 
Steve

From timomlists at gmail.com  Fri Apr 24 12:21:32 2015
From: timomlists at gmail.com (Timo)
Date: Fri, 24 Apr 2015 12:21:32 +0200
Subject: [Tutor] Spongebob Pythonpants
In-Reply-To: <CALRAYNWPB_W7bReHHH_gAsHKdsBwJaOie7qPJ_QD0g56GetQ6w@mail.gmail.com>
References: <CALRAYNWPB_W7bReHHH_gAsHKdsBwJaOie7qPJ_QD0g56GetQ6w@mail.gmail.com>
Message-ID: <553A192C.7050402@gmail.com>

Op 24-04-15 om 04:37 schreef Jim Mooney:
> I was depressed at the thought of learning unicode, then discovered Python
> was fun again since I can easily print any ascii art from
> http://www.chris.com/ascii/  with a multiline print, so long as I replace
> any backslash with two of them.
You can save yourself some time and use a raw string:
print(r"""   <the original SpongeBob here>   """)

Timo


> Spongebob Squarepants was, of course, the
> obvious first choice. The heck with Tkinter. (Bob is coming out a bit thin
> in my gmail but looks fine in the REPL.)
>
> print('''
>        .--..--..--..--..--..--.
>      .' \\  (`._   (_)     _   \\
>    .'    |  '._)         (_)  |
>    \\ _.')\\      .----..---.   /
>    |(_.'  |    /    .-\\-.  \\  |
>    \\     0|    |   ( O| O) | o|
>     |  _  |  .--.____.'._.-.  |
>     \\ (_) | o         -` .-`  |
>      |    \\   |`-._ _ _ _ _\\ /
>      \\    |   |  `. |_||_|   |
>      | o  |    \\_      \\     |     -.   .-.
>      |.-.  \\     `--..-'   O |     `.`-' .'
>    _.'  .' |     `-.-'      /-.__   ' .-'
> .' `-.` '.|='=.='=.='=.='=|._/_ `-'.'
> `-._  `.  |________/\\_____|    `-.'
>     .'   ).| '=' '='\\/ '=' |
>     `._.`  '---------------'
>             //___\\   //___\\
>               ||       ||
>      LGB      ||_.-.   ||_.-.
>              (_.--__) (_.--__)''')
>
>
> *** Remote Interpreter Reinitialized  ***
>        .--..--..--..--..--..--.
>      .' \  (`._   (_)     _   \
>    .'    |  '._)         (_)  |
>    \ _.')\      .----..---.   /
>    |(_.'  |    /    .-\-.  \  |
>    \     0|    |   ( O| O) | o|
>     |  _  |  .--.____.'._.-.  |
>     \ (_) | o         -` .-`  |
>      |    \   |`-._ _ _ _ _\ /
>      \    |   |  `. |_||_|   |
>      | o  |    \_      \     |     -.   .-.
>      |.-.  \     `--..-'   O |     `.`-' .'
>    _.'  .' |     `-.-'      /-.__   ' .-'
> .' `-.` '.|='=.='=.='=.='=|._/_ `-'.'
> `-._  `.  |________/\_____|    `-.'
>     .'   ).| '=' '='\/ '=' |
>     `._.`  '---------------'
>             //___\   //___\
>               ||       ||
>      LGB      ||_.-.   ||_.-.
>              (_.--__) (_.--__)
>


From alan.gauld at btinternet.com  Fri Apr 24 13:24:59 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 24 Apr 2015 12:24:59 +0100
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <mhd0bc$iu8$1@ger.gmane.org>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
 <55398165.3050401@btinternet.com> <20150424024619.GT5663@ando.pearwood.info>
 <mhd0bc$iu8$1@ger.gmane.org>
Message-ID: <mhd969$6ta$1@ger.gmane.org>

On 24/04/15 09:54, Alan Gauld wrote:

> numbers or other symbols so there were two sets of meanings to
> each pattern and a shift pattern to switch between them (which is
> why we have SHIFT keys on modern keyboards).

Sorry, I'm conflating two sets of issues here.
The SHIFT key pre-dated teleprinters from the typewriter. The
reason was the same: the physical carriage had to mechanically
shift up so that the second set of characters would be printed.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From steve at pearwood.info  Fri Apr 24 15:41:56 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Apr 2015 23:41:56 +1000
Subject: [Tutor] How to close a Tkinter window from a different thread?
In-Reply-To: <CANDiX9LVDvbYoaVSzvLJeFpjqJrKf=Yt79nNnVtKXHbZ6ooKZA@mail.gmail.com>
References: <CANDiX9LVDvbYoaVSzvLJeFpjqJrKf=Yt79nNnVtKXHbZ6ooKZA@mail.gmail.com>
Message-ID: <20150424134155.GX5663@ando.pearwood.info>

Coming in late to this conversation... 


On Sun, Apr 19, 2015 at 10:34:43PM -0500, boB Stepp wrote:

> Scenario B:
> 1) I start out inside the CSA.
> 2) I initiate a script in the CSA's scripting language.
> 3) This script calls an external Python script in a new thread.
> 4) This Python script generates a Tkinter window, populating it with
> information from the CSA.
> 5) Control returns to the CSA while the Tkinter window is populating
> itself. The CSA's tools can be used while the Tkinter window remains
> open displaying its information.

I think one way of doing this is by making the Python script a daemon 
that runs in the background. That at least will solve the problem from 
Scenario A that the CSA becomes unresponsive while the Tkinter window is 
open: as far as the CSA is concerned, the process it launched has ended.

Three follow-up problems then occur:

- Can daemons run as graphical applications?

- Once the daemon is running, how does the CSA communicate with it?

- How do we make sure that the daemon closes down safely when the 
  CSA quits?


I don't know the answers to these.

Ben Finney maintains a Python daemon library. If Ben is around, he may 
be able to shed some further light onto this question, and answer 
whether a daemon is suitable. Perhaps even give some sample code.



-- 
Steve

From robertvstepp at gmail.com  Fri Apr 24 19:23:19 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 24 Apr 2015 12:23:19 -0500
Subject: [Tutor] How to close a Tkinter window from a different thread?
In-Reply-To: <20150424134155.GX5663@ando.pearwood.info>
References: <CANDiX9LVDvbYoaVSzvLJeFpjqJrKf=Yt79nNnVtKXHbZ6ooKZA@mail.gmail.com>
 <20150424134155.GX5663@ando.pearwood.info>
Message-ID: <CANDiX9JUYqoP3hX57b2nB4qhYUWS=4ms83UbaL0NAdkdrF+ipQ@mail.gmail.com>

On Fri, Apr 24, 2015 at 8:41 AM, Steven D'Aprano <steve at pearwood.info> wrote:

> On Sun, Apr 19, 2015 at 10:34:43PM -0500, boB Stepp wrote:
>
>> Scenario B:
>> 1) I start out inside the CSA.
>> 2) I initiate a script in the CSA's scripting language.
>> 3) This script calls an external Python script in a new thread.
>> 4) This Python script generates a Tkinter window, populating it with
>> information from the CSA.
>> 5) Control returns to the CSA while the Tkinter window is populating
>> itself. The CSA's tools can be used while the Tkinter window remains
>> open displaying its information.
>
> I think one way of doing this is by making the Python script a daemon
> that runs in the background. That at least will solve the problem from
> Scenario A that the CSA becomes unresponsive while the Tkinter window is
> open: as far as the CSA is concerned, the process it launched has ended.

This part sounds promising.

> Three follow-up problems then occur:
>
> - Can daemons run as graphical applications?
>
> - Once the daemon is running, how does the CSA communicate with it?

I'd be extremely interested if this is possible! My biggest struggles
are exchanging information between the CSA and other programs external
to it. And it is much harder going in one direction than the other.
Liberal use of temp files seems to be the most reliable means of
exchanging information, though some exploitation of the CSA's global
variables is possible, though this is usually a last ditch effort when
nothing else seems to work.

> - How do we make sure that the daemon closes down safely when the
>   CSA quits?
>
>
> I don't know the answers to these.
>
> Ben Finney maintains a Python daemon library. If Ben is around, he may
> be able to shed some further light onto this question, and answer
> whether a daemon is suitable. Perhaps even give some sample code.

I'll keep my fingers crossed!

-- 
boB

From lac at openend.se  Fri Apr 24 13:04:57 2015
From: lac at openend.se (Laura Creighton)
Date: Fri, 24 Apr 2015 13:04:57 +0200
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: Message from "Steven D'Aprano" <steve@pearwood.info> of "Fri,
 24 Apr 2015 12:46:20 +1000." <20150424024619.GT5663@ando.pearwood.info>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
 <55398165.3050401@btinternet.com><20150424024619.GT5663@ando.pearwood.info>
Message-ID: <201504241104.t3OB4vvt017540@fido.openend.se>

In a message of Fri, 24 Apr 2015 12:46:20 +1000, "Steven D'Aprano" writes:
>The Japanese, Chinese and Korean 
>governments, as well as linguists, are all in agreement that despite a 
>few minor differences, the three languages share a common character set.

I don't think that is quite the way to say it.  There are characters,
which look exactly the same in all three languages, and the linguists
are mostly in agreement that the reason they look the same is that the
are the same.

But it is more usual to write Korean, these days, not with Chinese
characters, (hanja) but with hangul.  In the 15th century, the King,
Sejong the great decided that Koreans needed a phoenetic alphabet, and
made one.   It doesn't look anything like chinese.  And it is a phonetic,
alphabetic langauge, not a stroke-and-character one.

Due to the fact that the aristocracy liked using the hanja
as they always had, it only really caught on in the 20th century.  So
if you deal with older historical Korean documents, knowing hanja will
be essential to you.  But if you just need modern Korean, you won't,
because these days, South Koreans write their language with hangul,
and a few Chinese characters tossed in on rare occasion, while
I am told that in North Korean they don't use any Chinese characters
at all.

for the unicode aspects,
see: http://en.wikipedia.org/wiki/Korean_language_and_computers

Laura

From robertvstepp at gmail.com  Fri Apr 24 21:09:45 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 24 Apr 2015 14:09:45 -0500
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
Message-ID: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>

I have just started reading "Test-Driven Development by Example" by
Kent Beck during my lunch breaks at work. This book was a suggestion
by Danny Yoo in another thread. So far it has been good reading. My
current programming work flow is to add a little bit of code, run a
*manual* test(s), inspect the results, correct anything that fails,
rerun my manual test(s), etc. Frequently I run the entire program to
see if anything has been damaged by the work so far. So TDD feels like
it would fit very well with what I already try to do *manually*. I've
known for a while that I need to move towards comprehensive automated
testing, and I finally feel I know enough Python that I can focus on
TDD and not be constantly struggling with Python syntax issues. And I
really like this idea of writing a test first, it fails, now make the
test pass, repeat.

My wife (A teacher.) has been after me a lot lately to write some
programs to make her teaching life better. So I would like to start
one of her projects using TDD from the get-go. Also, this sounds like
a good time to try to implement using version control software. While
setting up Vim recently, I had to install Git (In order to get Vundle
going.). So now I have that to play with. And to throw more fuel onto
the fire of learning, why not jump into OOP for this project as well?
It's about time! Plus it will make life with Tkinter a bit better,
too.

The project(s) will be coded in Python 3.4 on Windows 7 64-bit on my
home computer. All projects that I actually complete for my wife will
be implemented in her classroom, which has quite a variety of hardware
and OS platforms: lap tops and desk tops, some of which are rather
old, running Windows XP, Windows 7, and Ubuntu Linux. And possibly
other combos that I have not been made aware of yet.

First question: What testing modules/frameworks should I start out
with? Doing a quick scan of the books I have, mention is made of
doctest and unittest modules in the Python standard libraries. But
mention is also made of two third party modules, nose and pytest. What
would be the most productive use of my learning time while entering
TDD waters for the first time? And beyond automating unit tests, how
is integration testing done in an automated fashion? Will I require
special software for this? And then there is user interface testing...

And what would be the best approach to integrating Git with these
efforts? Just how often does one commit one's code to the version
control system? Or do I have some GCEs (Gross Conceptual Errors) here?
Can Git be set up to automatically keep track of my code as I create
and edit it?

And as to automated testing: I really, ..., really would like to
implement it on my side projects at work. But all such programs start
in a proprietary scripting environment, which can call external Python
(or other languages) scripts. The resulting final program is almost
always an unavoidable amount of propriety scripting language (Which I
always strive to minimize the amount of.), Solaris shell
commands/scripts and Python. As I have been learning more Python and
implementing it at work, I have found that the most successful
approach seems to be to first get all of the information I need out of
the CSA (commercial software environment) upfront, save it in temp
files, then call a Python script to start the heavy duty processing,
do everything possible in Python, generate a "reload" script file that
contains language the CSA understands, and finally run that inside the
CSA. How do I go about automating the testing of something like this?
And apply TDD write tests first principles?

And I would like to have all of that under version control, too. But
while I am allowed to write my own programs for this CSA, I am not
allowed to install anything else, strange as this may sound! Since the
only functional editors in these bare-bones Solaris 10 environments
are some simplistic default editor that I do not know the name of and
vi, I long ago gravitated to doing my actual coding on my Windows PC
(Being careful to save things with Unix line endings.) and FTPing to
the environments where these programs will actually run. I AM allowed
to install anything I want (within reason)on my PC. So I am thinking
install and use Git there?

And if successful automated testing can be done with this CSA
situation, how difficult is it to backtrack and add test suites to
stuff already written and being used? Are there special strategies and
techniques for accomplishing such a feat?

And any other suggestions to best start learning all of this as well
as possible?

As always, many thanks in advance!


-- 
boB

From alan.gauld at btinternet.com  Sat Apr 25 00:03:04 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 24 Apr 2015 23:03:04 +0100
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
Message-ID: <mheeim$unl$1@ger.gmane.org>

On 24/04/15 20:09, boB Stepp wrote:
> I have just started reading "Test-Driven Development by Example" by
> Kent Beck during my lunch breaks at work.

The TDD bit is another whole topic that I'll probably jump into later.
For now...

> allowed to install anything else, strange as this may sound! Since the
> only functional editors in these bare-bones Solaris 10 environments
> are some simplistic default editor that I do not know the name of and
> vi,

vi is a great editor, no major problems there, except it
doesn't have Python syntax awareness/coloring etc.
.
However from memory doesn't Solaris 10 come with a CDE GUI?
If so it should have a graphical editor in there someplace too.
It was a reasonable coding editor in that it did block indenting,
bracket matching, etc.

And of course it has the original SCCS for source control.
Which if there's only a few of you is adequate, and easy
to work with. I used SCCS on several major projects over
a 10 year period.

> And if successful automated testing can be done with this CSA
> situation, how difficult is it to backtrack and add test suites to
> stuff already written and being used?

That's the traditional way of doing testing! Its not that hard
if you can figure out a test environment. but from what I recall
this CSA is a GUI? That makes injecting messages/commands much
harder. There are tools that can do it but you can't install
them...

In your case building a usable test environment may be the
barrier, building the test is an evolutionary process that
shouldn't be too hard.

If you have a CLI interface then file redirection makes
it relatively easy! If you can interact with its database
then stored procedures might provide away in.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From lac at openend.se  Fri Apr 24 22:00:24 2015
From: lac at openend.se (Laura Creighton)
Date: Fri, 24 Apr 2015 22:00:24 +0200
Subject: [Tutor] Introductory questions on test-driven development and
	implementing Git version control.
In-Reply-To: Message from boB Stepp <robertvstepp@gmail.com> of "Fri,
 24 Apr 2015 14:09:45 -0500."
 <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
Message-ID: <201504242000.t3OK0OoB001036@fido.openend.se>

In a message of Fri, 24 Apr 2015 14:09:45 -0500, boB Stepp writes:

>First question: What testing modules/frameworks should I start out
>with? Doing a quick scan of the books I have, mention is made of
>doctest and unittest modules in the Python standard libraries. But
>mention is also made of two third party modules, nose and pytest. What
>would be the most productive use of my learning time while entering
>TDD waters for the first time? And beyond automating unit tests, how
>is integration testing done in an automated fashion? Will I require
>special software for this? And then there is user interface testing...

You need the testing-in-python mailing list.  Come on over ...
http://lists.idyll.org/listinfo/testing-in-python
You will find lots of familiar faces (email addresses) from this
list there.  Nose and py.test are very similar.  I happen to like
them better than unittest, but if you cannot install software on
your solaris machines, you may be better off with unittest which
comes with Python, which I assume you do have on your Solaris boxes.

>And what would be the best approach to integrating Git with these
>efforts? Just how often does one commit one's code to the version
>control system? Or do I have some GCEs (Gross Conceptual Errors) here?
>Can Git be set up to automatically keep track of my code as I create
>and edit it?

Depending on what you mean by that, the answer is 'no' or 'that is
exactly what git does, there is no way to _prevent_ this'.

You have to tell git when you would like to save your work.
It doesn't work like autosaving in an editor -- hah hah, she has typed
300 chars now,  (or it has been 5 minutes now) time to autosave -- if
you never tell git to save the work, it will never get saved.

So what you typically do is write a test, tell git to save it, run the
test, have it fail, write some more code and run  all the tests again,
have them pass, tell git to save it, write another test ...

If in the 'write some more code' part, you get the itch 'it would be
really bad if my laptop died and I lost all this work' you tell git to
save immediately and keep on going.

There is a whole other layer about 'how to share your code with other
people, politely, when several of you are working on the same project
at one time, but if you are a one man team, you won't have to worry
about that for a while.

>And as to automated testing: I really, ..., really would like to
>implement it on my side projects at work. But all such programs start
>in a proprietary scripting environment, which can call external Python
>(or other languages) scripts. The resulting final program is almost
>always an unavoidable amount of propriety scripting language (Which I
>always strive to minimize the amount of.), Solaris shell
>commands/scripts and Python. As I have been learning more Python and
>implementing it at work, I have found that the most successful
>approach seems to be to first get all of the information I need out of
>the CSA (commercial software environment) upfront, save it in temp
>files, then call a Python script to start the heavy duty processing,
>do everything possible in Python, generate a "reload" script file that
>contains language the CSA understands, and finally run that inside the
>CSA. How do I go about automating the testing of something like this?
>And apply TDD write tests first principles?

You need the testing-in-python mailing list.  Whatever proprietary
thing you have  to integrate with, chances are somebody there has
been there, and done that already and has code you would be
welcome to use.

>And I would like to have all of that under version control, too. But
>while I am allowed to write my own programs for this CSA, I am not
>allowed to install anything else, strange as this may sound! Since the
>only functional editors in these bare-bones Solaris 10 environments
>are some simplistic default editor that I do not know the name of and
>vi, I long ago gravitated to doing my actual coding on my Windows PC
>(Being careful to save things with Unix line endings.) and FTPing to
>the environments where these programs will actually run. I AM allowed
>to install anything I want (within reason)on my PC. So I am thinking
>install and use Git there?

Are you absolutely certain that you cannot install git on your bare-bones
Solaris 10 environments?  Or plug in a memory stick and run code from
there?  Because it would make your life so much easier ...
>
>And if successful automated testing can be done with this CSA
>situation, how difficult is it to backtrack and add test suites to
>stuff already written and being used? Are there special strategies and
>techniques for accomplishing such a feat?

Lots and lots.

>And any other suggestions to best start learning all of this as well
>as possible?
>
>As always, many thanks in advance!
>
>
>-- 
>boB

Laura


From robertvstepp at gmail.com  Sat Apr 25 00:52:50 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 24 Apr 2015 17:52:50 -0500
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <mheeim$unl$1@ger.gmane.org>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
 <mheeim$unl$1@ger.gmane.org>
Message-ID: <CANDiX9Jk9rYOgQSYSTG0af5TfWPkWbBCZOPKVMM7bcbUqTwWpQ@mail.gmail.com>

On Fri, Apr 24, 2015 at 5:03 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 24/04/15 20:09, boB Stepp wrote:
>>

>> allowed to install anything else, strange as this may sound! Since the
>> only functional editors in these bare-bones Solaris 10 environments
>> are some simplistic default editor that I do not know the name of and
>> vi,
>
>
> vi is a great editor, no major problems there, except it
> doesn't have Python syntax awareness/coloring etc.

I am quite happy with vi! I did not mean to imply otherwise. However,
as you know I have only very recently started using Vim at home and
don't consider myself productive in it yet. My game plan, is once I
do, to start doing my editing at work directly in Solaris 10 on vi.

> However from memory doesn't Solaris 10 come with a CDE GUI?
> If so it should have a graphical editor in there someplace too.
> It was a reasonable coding editor in that it did block indenting,
> bracket matching, etc.

Your memory is indeed correct as to CDE. It has a default graphical
editor, the one I referred to as "simplistic", but if it has those
features I have missed them. When I say "default", it is this editor
that will pop up if I open a file for editing. I will look through the
menus and help again. Maybe I gave it short shrift too soon! That does
not mean that there is not another graphical editor in there
somewhere. I will poke around some more. But it seems, Alan, that
whenever I look for something that is *supposed* to be there, I find
basically a stub of an application that is missing required libraries,
etc. The installers of the planning software deliberately do NOT
install a substantial amount of what would normally be there in any
*normal* installation of Solaris. I once *begged* the support people
for this planning system to install the missing stuff for Emacs, but
they refused. Of course, this is after I found someone who even knew
what Emacs was, but that is another story...

But I may have to revisit all of this. We went to "Smart Enterprise"
on this software about a year ago. I managed to abscond with one of
the 810X boxes, with the planning software intact. I got my
administration to let me keep it as my development and testing
environment, since they do value the programs I generate (Whenever I
get time to work on them, which is usually rare.). I think now that as
long as I stay on this box, that no one will mind if I install
anything. I just need not to do so on our Smart Enterprise  clinical
planning environment. I actually started to explore this route about a
half-year or so ago, having figured out how to get the 810X connected
to the Internet, but then I got distracted since by what they really
pay me to do!

> And of course it has the original SCCS for source control.
> Which if there's only a few of you is adequate, and easy
> to work with. I used SCCS on several major projects over
> a 10 year period.

There is just lil ol' me. I will have to research SCCS.

>> And if successful automated testing can be done with this CSA
>> situation, how difficult is it to backtrack and add test suites to
>> stuff already written and being used?
>
>
> That's the traditional way of doing testing! Its not that hard
> if you can figure out a test environment. but from what I recall
> this CSA is a GUI? That makes injecting messages/commands much
> harder. There are tools that can do it but you can't install
> them...

It is a GUI. If I can initiate the testing process from within the CSA
with a small script in its language AND have the testing software
generate appropriate files in the CSA's language, then I can see how
it all would work. But it sounds like I would have to write (and test)
an interface program between the two. Of course I am just starting the
path to learning TDD, so that will probably be at least a little ways
off...

> In your case building a usable test environment may be the
> barrier, building the test is an evolutionary process that
> shouldn't be too hard.

I guess this is what I was thinking about just above...

> If you have a CLI interface then file redirection makes
> it relatively easy! If you can interact with its database
> then stored procedures might provide away in.

I do. But I don't see where you are going with this yet as I do not
know enough about how these testing enviroments, etc. work yet.


-- 
boB

From steve at pearwood.info  Sat Apr 25 02:36:57 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 25 Apr 2015 10:36:57 +1000
Subject: [Tutor] Introductory questions on test-driven development and
	implementing Git version control.
In-Reply-To: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
Message-ID: <20150425003654.GB5663@ando.pearwood.info>

So many questions... let's hope I don't miss any... :-)

On Fri, Apr 24, 2015 at 02:09:45PM -0500, boB Stepp wrote:

> First question: What testing modules/frameworks should I start out
> with? Doing a quick scan of the books I have, mention is made of
> doctest and unittest modules in the Python standard libraries. But
> mention is also made of two third party modules, nose and pytest.

Doctest is the simplest but less powerful. And besides, unless you are 
Tim Peters, the creator of doctest, nobody wants to read dozens and 
dozens of tests in a function docstring.

unittest is quite easy to use, and powerful. Some people complain that 
it is not very Pythonic, but I've never felt that. It is also based on a 
standard and much-copied Java library, so there are versions of unittest 
for many different languages. I quite like it.

I've never used nose, but from what I have seen of it, I will not like 
it. I understand that it extensively uses the assert statement for 
testing, which I believe is naughty: it is, I maintain, a misuse of 
assert. It's okay to use a few assert statements for quick and informal 
testing, but not for permanent professional testing. 

If nothing else, by using assert for your tests, you cannot possibly 
test your code when running under -O optimization.

I have no opinion on pytest.


> What
> would be the most productive use of my learning time while entering
> TDD waters for the first time? And beyond automating unit tests, how
> is integration testing done in an automated fashion? Will I require
> special software for this? And then there is user interface testing...

The different sorts of tests are separated by purpose, not necessarily 
form or usage. Particularly for small projects, it may not make sense to 
split them into separate test runs. It's okay to mix regression tests 
into your unit tests, and even integration testing, if they are simple 
and fast enough.

As for automated UI testing, that's hard unless you have a framework 
that is designed for that, something which can interact with the GUI 
controls and verify that they behave as expected. I have no idea about 
that.

In any case, you should be able to run all the tests (be they doc tests, 
unit tests, regression tests, etc.) from a single command. I like to set 
things up so that these will work:

python3 myproject/tests.py

python3 -m myproject.tests

If the integration tests are slow and complex, then you might have two 
test files, one which runs everything, and the other which runs 
everything but the integration tests. Run the quick tests frequently, 
and the slow tests less often.


> And what would be the best approach to integrating Git with these
> efforts? Just how often does one commit one's code to the version
> control system? Or do I have some GCEs (Gross Conceptual Errors) here?
> Can Git be set up to automatically keep track of my code as I create
> and edit it?

No, that's not how revision control works. You really don't want every 
time you hit save to count as a new revision. That would be ugly.

Joel Spolsky has a good introduction to Mercurial (hg). Git is slightly 
different, but the fundamentals are more or less equivalent:

http://hginit.com/
?
You can also watch Git For Ages 4 And Up:

http://www.youtube.com/watch?v=1ffBJ4sVUb4


The executive summary of how I use version control:

- work on bite-sized chunks of functionality
- when the tests all pass, commit the work done
- push changes to the master repo at least once per day


The way I use version control on my own is that I have typically use a 
single branch. I rarely have to worry about contributions from others, 
so it's just my changes. Make sure that all the relevent files (source 
code, documentation, tests, images, etc.) are being tracked. Static 
files which never change, like reference materials, should not be.

Starting from a point where all the tests pass, I decide to work on a 
new feature, or fix a bug. A feature might be something as small as "fix 
the documentation for this function", but *not* as big as "control 
remote controlled space ship" -- in other words, a bite-sized chunk of 
work, not a full meal. I write some tests, and write the minimal amount 
of code code that makes those tests pass:

- write tests
- save tests
- write code
- save code
- run tests
- fix bugs in tests
- save tests
- write some more code
- save code
- run tests again
- write some more code
- save code
- run tests again


etc. Once the tests pass, then I have a feature and/or bug fix, and I 
commit all the relevent changes to the VCS. hg automatically tracks 
files, git requires you to remind it every single time what files are 
being used, but either way, by the time I run `hg commit` or `git 
commit` I have a complete, and hopefully working, bite-sized chunk of 
code that has an obvious commit message:

"fix bug in spam function"
"correct spelling errors in module docs"
"rename function ham to spam"
"change function eggs from using a list to a dict"
"move class K into its own submodule"

etc. Notice that each change is small enough to encapsulate in a short 
description, but big enough that some of them may require multiple 
rounds of back-and-forth code-and-test before it works.

I run the tests even after seemingly innoculous changes to comments or 
docstrings, especially docstrings. Edits to a docstring may break your 
doctests, or even your code, if you accidentally break the quoting.

Then, when I am feeling satisfied that I've done a sufficiently large 
amount of work, I then push those changes to the master repo (if any). 
This allows me to work from various computers and still share the same 
code base. "Sufficiently large" may mean a single change, or a full 
day's work, or a whole lot of related changes that add up to one big 
change, whatever you prefer. But it shouldn't be less than once per day.


> And as to automated testing: I really, ..., really would like to
> implement it on my side projects at work. But all such programs start
> in a proprietary scripting environment, which can call external Python
> (or other languages) scripts. The resulting final program is almost
> always an unavoidable amount of propriety scripting language (Which I
> always strive to minimize the amount of.), Solaris shell
> commands/scripts and Python. As I have been learning more Python and
> implementing it at work, I have found that the most successful
> approach seems to be to first get all of the information I need out of
> the CSA (commercial software environment) upfront, save it in temp
> files, then call a Python script to start the heavy duty processing,
> do everything possible in Python, generate a "reload" script file that
> contains language the CSA understands, and finally run that inside the
> CSA. How do I go about automating the testing of something like this?
> And apply TDD write tests first principles?

TDD principles apply to any programming language. So long as the 
language that you use to write the tests has ways of calling your shell 
scripts and CSA code, and seeing what results they get, you can test 
them.

For example, I might write a test which calls a shell script using 
os.system, and checks that the return result is 0 (success). And a 
second test that confirms that the shell script actually generates the 
file that it is supposed to. A third test to confirm that it cleans up 
after itself. Etc.


> And I would like to have all of that under version control, too. But
> while I am allowed to write my own programs for this CSA, I am not
> allowed to install anything else, strange as this may sound! Since the
> only functional editors in these bare-bones Solaris 10 environments
> are some simplistic default editor that I do not know the name of and
> vi, I long ago gravitated to doing my actual coding on my Windows PC
> (Being careful to save things with Unix line endings.) and FTPing to
> the environments where these programs will actually run. I AM allowed
> to install anything I want (within reason)on my PC. So I am thinking
> install and use Git there?

Yes.


> And if successful automated testing can be done with this CSA
> situation, how difficult is it to backtrack and add test suites to
> stuff already written and being used? Are there special strategies and
> techniques for accomplishing such a feat?

It's easy, especially for doc and unit tests, which is why I personally 
don't care too much about actually writing the tests first. For me, at 
least, it doesn't matter which gets written first.

However, I *religiously* write the documentation first. If I don't 
document what the function does, how will I know what the code should 
do or when I am finished?


-- 
Steve

From cybervigilante at gmail.com  Sat Apr 25 01:03:37 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Fri, 24 Apr 2015 16:03:37 -0700
Subject: [Tutor] Spongebob Pythonpants
In-Reply-To: <553A192C.7050402@gmail.com>
References: <CALRAYNWPB_W7bReHHH_gAsHKdsBwJaOie7qPJ_QD0g56GetQ6w@mail.gmail.com>
 <553A192C.7050402@gmail.com>
Message-ID: <CALRAYNVD+jJO6DUR2w6KP1R9Bs_H7Q64_sRt-2MHARbZBExCqw@mail.gmail.com>

You can save yourself some time and use a raw string:

> print(r"""   <the original SpongeBob here>   """)
>
> Timo
>
> Good point. I'll go to site-packages and change that. I import Bob to
cheer myself up as I look at Unicode, which is like forcing a kid to go to
Sunday school on a bright Summer day, instead of playing with Python. I
wonder if there's a Unicode for Idiots book ;')

Jim

From alan.gauld at btinternet.com  Sat Apr 25 02:46:18 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 25 Apr 2015 01:46:18 +0100
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <CANDiX9Jk9rYOgQSYSTG0af5TfWPkWbBCZOPKVMM7bcbUqTwWpQ@mail.gmail.com>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
 <mheeim$unl$1@ger.gmane.org>
 <CANDiX9Jk9rYOgQSYSTG0af5TfWPkWbBCZOPKVMM7bcbUqTwWpQ@mail.gmail.com>
Message-ID: <mheo4n$9vq$1@ger.gmane.org>

On 24/04/15 23:52, boB Stepp wrote:

> There is just lil ol' me. I will have to research SCCS.

SCCS is great for a single, small team. It's marginally more complex 
than more modern tools and it only works sensibly with text files 
(binaries are just uuencoded which is pretty pointless!).

Basic usage is very simple:
1) create an SCCS directory in your project space - or you wind up with 
version files all over the place!
2) use the admin -i command to tell sccs to manage a file
3) use get to get a read only copy or get -e to get an editable one. 
(use -r to get a specific version)
4) use delta to save changes (it prompts you for change comments etc)

There are a bunch of other reporting and searching and admin
commands, but the above is all you need 90% of the time.
More modern versioning systems are better but SCCS should already
be installed on Solaris 10 if you have the development tools
installed, which I'm guessing you do or pretty much
nothing code-wise would work.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From cybervigilante at gmail.com  Sat Apr 25 01:34:19 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Fri, 24 Apr 2015 16:34:19 -0700
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <20150424100800.GV5663@ando.pearwood.info>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
 <20150424100800.GV5663@ando.pearwood.info>
Message-ID: <CALRAYNVgRavwep95VfDjqsTz6yCVQgtrdsdpXfat_bDGFZfCyQ@mail.gmail.com>

>
> Apparently so. It looks like utf_8-sig just ignores the sig if it is
> present, and uses UTF-8 whether the signature is present or not.
>
> That surprises me.
>
> --
> Steve
> ____________
>

I was looking things up and although there are aliases for utf_8 (utf8 and
utf-8) I see no aliases for utf_8_sig, so I'm surprised the utf-8-sig I
tried using, worked at all. Actually, I was trying to find the file where
the aliases are so I could change it and have utf_8_sig called up when I
used utf8, but it appears to be hard-coded.
-- 
Jim

From cybervigilante at gmail.com  Sat Apr 25 01:43:35 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Fri, 24 Apr 2015 16:43:35 -0700
Subject: [Tutor] sig no matter what
Message-ID: <CALRAYNVGiqTW72HF8g399RjJgqUg+zjoS0ZThsEvvFRfDzFEpQ@mail.gmail.com>

It looks like sig works for any dash, underline combination, and is ignored
if there is no BOM:

>>> farf = bytes('many moons ago I sat on a rock', encoding='utf8')
>>> farf
b'many moons ago I sat on a rock'
>>> str(farf, encoding="utf_8_sig")
'many moons ago I sat on a rock'
>>> str(farf, encoding="utf-8-sig")
'many moons ago I sat on a rock'
>>> str(farf, encoding="utf_8-sig")
'many moons ago I sat on a rock'
>>> str(farf, encoding="utf-8_sig")
'many moons ago I sat on a rock'

-- 
Jim

Then: "Get rich flipping houses, with No Money Down!" Now: "Get rich making
the next great app, with No Programming!" There's always a sucker for
get-rich-quick schemes.

From cybervigilante at gmail.com  Sat Apr 25 02:19:33 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Fri, 24 Apr 2015 17:19:33 -0700
Subject: [Tutor] Making an alias
Message-ID: <CALRAYNVCfoJcfBZXP8tCULhQWktUKtDudBH5-3g4e4r=-Yn8cw@mail.gmail.com>

Actually,. I found the aliases in Lib/encodings/aliases.py and added an
alias:

>>> deco = bytes("I sure hate apples.", encoding='ubom')
>>> deco
b'\xef\xbb\xbfI sure hate apples.'
>>>

Tricky, though - if you don't put a comma at the end of your alias, it
breaks Python (or my Pyscripter editor, anyway ;')
-- 
Jim

From steve at pearwood.info  Sat Apr 25 02:50:30 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 25 Apr 2015 10:50:30 +1000
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <CALRAYNVgRavwep95VfDjqsTz6yCVQgtrdsdpXfat_bDGFZfCyQ@mail.gmail.com>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
 <20150424100800.GV5663@ando.pearwood.info>
 <CALRAYNVgRavwep95VfDjqsTz6yCVQgtrdsdpXfat_bDGFZfCyQ@mail.gmail.com>
Message-ID: <20150425005029.GD5663@ando.pearwood.info>

On Fri, Apr 24, 2015 at 04:34:19PM -0700, Jim Mooney wrote:

> I was looking things up and although there are aliases for utf_8 (utf8 and
> utf-8) I see no aliases for utf_8_sig, so I'm surprised the utf-8-sig I
> tried using, worked at all. Actually, I was trying to find the file where
> the aliases are so I could change it and have utf_8_sig called up when I
> used utf8, but it appears to be hard-coded.

I believe that Python's codecs system automatically normalises the 
encoding name by removing spaces, dashes and underscores, but I'm afraid 
that either I don't understand how it works or it is buggy:

py> 'Hello'.encode('utf___---___  -- ___8')  # Works.
b'Hello'

py> 'Hello'.encode('ut-f8')  # Fails.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
LookupError: unknown encoding: ut-f8


-- 
Steve

From breamoreboy at yahoo.co.uk  Sat Apr 25 02:52:38 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sat, 25 Apr 2015 01:52:38 +0100
Subject: [Tutor] Spongebob Pythonpants
In-Reply-To: <CALRAYNVD+jJO6DUR2w6KP1R9Bs_H7Q64_sRt-2MHARbZBExCqw@mail.gmail.com>
References: <CALRAYNWPB_W7bReHHH_gAsHKdsBwJaOie7qPJ_QD0g56GetQ6w@mail.gmail.com>
 <553A192C.7050402@gmail.com>
 <CALRAYNVD+jJO6DUR2w6KP1R9Bs_H7Q64_sRt-2MHARbZBExCqw@mail.gmail.com>
Message-ID: <mheogq$f00$1@ger.gmane.org>

On 25/04/2015 00:03, Jim Mooney wrote:
> You can save yourself some time and use a raw string:
>
>> print(r"""   <the original SpongeBob here>   """)
>>
>> Timo
>>
>> Good point. I'll go to site-packages and change that. I import Bob to
> cheer myself up as I look at Unicode, which is like forcing a kid to go to
> Sunday school on a bright Summer day, instead of playing with Python. I
> wonder if there's a Unicode for Idiots book ;')
>
> Jim

Unicode for Idiots indeed, a Python list can always find something 
better than that :)

http://www.joelonsoftware.com/articles/Unicode.html
http://nedbatchelder.com/text/unipain.html

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From davea at davea.name  Sat Apr 25 02:53:30 2015
From: davea at davea.name (Dave Angel)
Date: Fri, 24 Apr 2015 20:53:30 -0400
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <CALRAYNVgRavwep95VfDjqsTz6yCVQgtrdsdpXfat_bDGFZfCyQ@mail.gmail.com>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
 <20150424100800.GV5663@ando.pearwood.info>
 <CALRAYNVgRavwep95VfDjqsTz6yCVQgtrdsdpXfat_bDGFZfCyQ@mail.gmail.com>
Message-ID: <553AE58A.4020205@davea.name>

On 04/24/2015 07:34 PM, Jim Mooney wrote:
>>
>> Apparently so. It looks like utf_8-sig just ignores the sig if it is
>> present, and uses UTF-8 whether the signature is present or not.
>>
>> That surprises me.
>>
>> --
>> Steve
>> ____________
>>
>
> I was looking things up and although there are aliases for utf_8 (utf8 and
> utf-8) I see no aliases for utf_8_sig, so I'm surprised the utf-8-sig I
> tried using, worked at all. Actually, I was trying to find the file where
> the aliases are so I could change it and have utf_8_sig called up when I
> used utf8, but it appears to be hard-coded.
>

I wouldn't use utf-8-sig for output, however, as it puts the BOM in the 
file for others to trip over.

-- 
DaveA

From robertvstepp at gmail.com  Sat Apr 25 03:24:38 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 24 Apr 2015 20:24:38 -0500
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <201504242000.t3OK0OoB001036@fido.openend.se>
References: <robertvstepp@gmail.com>
 <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
 <201504242000.t3OK0OoB001036@fido.openend.se>
Message-ID: <CANDiX9LY7nF7g0iezmmHmoptgMgDrFKxic=pbt8qgUntYTsXbg@mail.gmail.com>

On Fri, Apr 24, 2015 at 3:00 PM, Laura Creighton <lac at openend.se> wrote:
> In a message of Fri, 24 Apr 2015 14:09:45 -0500, boB Stepp writes:

> You need the testing-in-python mailing list.  Come on over ...
> http://lists.idyll.org/listinfo/testing-in-python
> You will find lots of familiar faces (email addresses) from this
> list there.  Nose and py.test are very similar.  I happen to like
> them better than unittest, but if you cannot install software on
> your solaris machines, you may be better off with unittest which
> comes with Python, which I assume you do have on your Solaris boxes.

I have joined!

The Python versions at work are 2.4.4 and 2.6.4(?)(Not certain about
the last digit there.) Based on responses to date, the fact that
unittest is in the standard library and that because of this most of
my books have something about unittest, I will probably start there. I
imagine that everything I learn with unittest will transfer over to
other testing frameworks.

>>And as to automated testing: I really, ..., really would like to
>>implement it on my side projects at work. But all such programs start
>>in a proprietary scripting environment, which can call external Python
>>(or other languages) scripts. The resulting final program is almost
>>always an unavoidable amount of propriety scripting language (Which I
>>always strive to minimize the amount of.), Solaris shell
>>commands/scripts and Python. As I have been learning more Python and
>>implementing it at work, I have found that the most successful
>>approach seems to be to first get all of the information I need out of
>>the CSA (commercial software environment) upfront, save it in temp
>>files, then call a Python script to start the heavy duty processing,
>>do everything possible in Python, generate a "reload" script file that
>>contains language the CSA understands, and finally run that inside the
>>CSA. How do I go about automating the testing of something like this?
>>And apply TDD write tests first principles?
>
> You need the testing-in-python mailing list.  Whatever proprietary
> thing you have  to integrate with, chances are somebody there has
> been there, and done that already and has code you would be
> welcome to use.

When I get farther along, I will probably have some very specific
questions on this that I will post there. Steven and Alan have given
me some very good feedback already! But if someone has already solved
my problem, or, something very similar, then that will be great!

>>And I would like to have all of that under version control, too. But
>>while I am allowed to write my own programs for this CSA, I am not
>>allowed to install anything else, strange as this may sound! Since the
>>only functional editors in these bare-bones Solaris 10 environments
>>are some simplistic default editor that I do not know the name of and
>>vi, I long ago gravitated to doing my actual coding on my Windows PC
>>(Being careful to save things with Unix line endings.) and FTPing to
>>the environments where these programs will actually run. I AM allowed
>>to install anything I want (within reason)on my PC. So I am thinking
>>install and use Git there?
>
> Are you absolutely certain that you cannot install git on your bare-bones
> Solaris 10 environments?  Or plug in a memory stick and run code from
> there?  Because it would make your life so much easier ...

I think that I can get an exception here (See a post in response that
I made earlier today.). What I am *certain* of, is that I cannot
install anything on our clinical planning environment. The Solaris
workstation that I now have all to myself--I'm thinking they will now
let me do what I want with it. But I must double check... But anything
I develop there *should* work in the clinical environment. The
planning software is the same though that may change soon as there are
plans to go up a version and they may not want to do that on my
testing/development machine.

Thanks!

-- 
boB

From eryksun at gmail.com  Sat Apr 25 04:24:55 2015
From: eryksun at gmail.com (eryksun)
Date: Fri, 24 Apr 2015 21:24:55 -0500
Subject: [Tutor] sig no matter what
In-Reply-To: <CALRAYNVGiqTW72HF8g399RjJgqUg+zjoS0ZThsEvvFRfDzFEpQ@mail.gmail.com>
References: <CALRAYNVGiqTW72HF8g399RjJgqUg+zjoS0ZThsEvvFRfDzFEpQ@mail.gmail.com>
Message-ID: <CACL+1auQaG3R4-J=B5CbXkSNaGw_-KwxuK7xMCFozXfCiyMNqg@mail.gmail.com>

On Fri, Apr 24, 2015 at 6:43 PM, Jim Mooney <cybervigilante at gmail.com> wrote:
> It looks like sig works for any dash, underline combination, and is ignored
> if there is no BOM:

See 7.2.3 (aliases) and 7.2.7 (utf_8_sig) in the codecs documentation.

https://docs.python.org/3/library/codecs.html

From robertvstepp at gmail.com  Sat Apr 25 05:15:20 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Fri, 24 Apr 2015 22:15:20 -0500
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <201504242000.t3OK0OoB001036@fido.openend.se>
References: <robertvstepp@gmail.com>
 <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
 <201504242000.t3OK0OoB001036@fido.openend.se>
Message-ID: <CANDiX9Ki5M7cz_1Q3heYqS9xU0Kj8bmZbS8amOz89jbQ1L3yZg@mail.gmail.com>

I saw something on Python-List that I think is worth getting on this
list as Mark gave a very good reference...

>Mark Lawrence wrote on Python-List:
>>On 25/04/2015 01:51, Terry Reedy wrote:

>>Based on my experience reading newbie posts on python list and
>>Stackoverflow, learning to write real functions, without input and
>>print, and repeatable tests, is the most important thing many people are
>>not learning from programming books and classes.


>Got to start them off somewhere so http://nedbatchelder.com/text/test0.html

It is a talk that Ned Batchelder gave at PyCon 2014 called, "Getting
Started Testing". You can watch the actual video (Which I just did.),
go through the slides or read the slides with the video comments
transcribed in. After watching the video, I feel I have a much greater
understanding of testing and Python's tools to support it than I did a
few minutes ago. I highly recommend watching this video -- Mr.
Batchelder is a very good speaker and presents his material very
effectively. Many thanks, Mark, for this link!

boB

From __peter__ at web.de  Sat Apr 25 10:21:11 2015
From: __peter__ at web.de (Peter Otten)
Date: Sat, 25 Apr 2015 10:21:11 +0200
Subject: [Tutor] Codec lookup, was Re: name shortening in a csv module output
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
 <20150424100800.GV5663@ando.pearwood.info>
 <CALRAYNVgRavwep95VfDjqsTz6yCVQgtrdsdpXfat_bDGFZfCyQ@mail.gmail.com>
 <20150425005029.GD5663@ando.pearwood.info>
Message-ID: <mhfipo$9v7$1@ger.gmane.org>

Steven D'Aprano wrote:

> On Fri, Apr 24, 2015 at 04:34:19PM -0700, Jim Mooney wrote:
> 
>> I was looking things up and although there are aliases for utf_8 (utf8
>> and utf-8) I see no aliases for utf_8_sig, so I'm surprised the utf-8-sig
>> I tried using, worked at all. Actually, I was trying to find the file
>> where the aliases are so I could change it and have utf_8_sig called up
>> when I used utf8, but it appears to be hard-coded.
> 
> I believe that Python's codecs system automatically normalises the
> encoding name by removing spaces, dashes and underscores, but I'm afraid
> that either I don't understand how it works or it is buggy:
> 
> py> 'Hello'.encode('utf___---___  -- ___8')  # Works.
> b'Hello'
> 
> py> 'Hello'.encode('ut-f8')  # Fails.
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> LookupError: unknown encoding: ut-f8

I don't think this is a bug.

Normalization of the name converts to lowercase and collapses arbitrary 
sequences of punctuation into a single "_".

The lookup that follows maps "utf8" to "utf_8" via a table:

>>> [n for n, v in encodings.aliases.aliases.items() if v == "utf_8"]
['utf8_ucs2', 'utf8', 'u8', 'utf', 'utf8_ucs4']

Hm, who the heck uses "u8"? I'd rather go with

>>> encodings.aliases.aliases["steven_s_preferred_encoding"] = "utf_8"
>>> "Hello".encode("--- Steven's preferred encoding ---")
b'Hello'

;)


From alan.gauld at btinternet.com  Sat Apr 25 10:21:37 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 25 Apr 2015 09:21:37 +0100
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
Message-ID: <mhfiqf$a95$1@ger.gmane.org>

Having looked at this thread and its early responses I think it
would be good to break it up into its two natural parts. TDD
and version control are pretty much separate concepts and
should be on separate threads.

Bob, could you please ask your version control questions again,
taking account of early responses, on a new thread? That way
we can keep the TDD stuff together and the version control
stuff in a separate place.

In particular the version control discussion will almost
certainly not be Python specific and generic to any kind
of programming - which makes it only marginally on-topic
for the tutor list.

Thanks,
-- 
Alan G
List moderator



From cybervigilante at gmail.com  Sat Apr 25 03:23:50 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Fri, 24 Apr 2015 18:23:50 -0700
Subject: [Tutor] Spongebob Pythonpants
In-Reply-To: <mheogq$f00$1@ger.gmane.org>
References: <CALRAYNWPB_W7bReHHH_gAsHKdsBwJaOie7qPJ_QD0g56GetQ6w@mail.gmail.com>
 <553A192C.7050402@gmail.com>
 <CALRAYNVD+jJO6DUR2w6KP1R9Bs_H7Q64_sRt-2MHARbZBExCqw@mail.gmail.com>
 <mheogq$f00$1@ger.gmane.org>
Message-ID: <CALRAYNWCtanGj=9yWa8eqLTkj8U5npdq2S2evnsSYU6X8dSoSA@mail.gmail.com>

Unicode for Idiots indeed, a Python list can always find something better
than that :)

>
> http://www.joelonsoftware.com/articles/Unicode.html
> http://nedbatchelder.com/text/unipain.html
>
>
> Mark Lawrence
>
>
Batcheder's looks good. I'm going through it. I tried the Unicode
Consortium website at unicode.org, but forget that - I'd rather pull my own
teeth than wade through it ;')

Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From cybervigilante at gmail.com  Sat Apr 25 03:43:16 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Fri, 24 Apr 2015 18:43:16 -0700
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <553AE58A.4020205@davea.name>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
 <20150424100800.GV5663@ando.pearwood.info>
 <CALRAYNVgRavwep95VfDjqsTz6yCVQgtrdsdpXfat_bDGFZfCyQ@mail.gmail.com>
 <553AE58A.4020205@davea.name>
Message-ID: <CALRAYNV2+q+Vphb7=pCgio+7btL-F+u=oBzY4OYd5FZCoE77Ww@mail.gmail.com>

>
>
> I wouldn't use utf-8-sig for output, however, as it puts the BOM in the
> file for others to trip over.
>
> --
> DaveA


Yeah, I found that out when I altered the aliases.py dictionary and added
'ubom' : 'utf_8_sig' as an item. Encoding didn't work out so good, but
decoding was fine ;')

From cybervigilante at gmail.com  Sat Apr 25 05:46:44 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Fri, 24 Apr 2015 20:46:44 -0700
Subject: [Tutor] sig no matter what
In-Reply-To: <CACL+1auQaG3R4-J=B5CbXkSNaGw_-KwxuK7xMCFozXfCiyMNqg@mail.gmail.com>
References: <CALRAYNVGiqTW72HF8g399RjJgqUg+zjoS0ZThsEvvFRfDzFEpQ@mail.gmail.com>
 <CACL+1auQaG3R4-J=B5CbXkSNaGw_-KwxuK7xMCFozXfCiyMNqg@mail.gmail.com>
Message-ID: <CALRAYNXS5FWUuACquaT2BZja-oK0JkPGzbVVWzW8LaDuCAkA1w@mail.gmail.com>

> See 7.2.3 (aliases) and 7.2.7 (utf_8_sig) in the codecs documentation.
>
> https://docs.python.org/3/library/codecs.html
>

The docs don't mention that case is immaterial for aliases, when it usually
matters in Python. The actual dictionary entries in aliases.py often differ
in case from the docs. For instance, this works:

>>> p = bytes("This sure sux", encoding="uTf32")
>>> p
b'\xff\xfe\x00\x00T\x00\x00\x00h\x00\x00\x00i\x00\x00\x00s\x00\x00\x00
\x00\x00\x00s\x00\x00\x00u\x00\x00\x00r\x00\x00\x00e\x00\x00\x00
\x00\x00\x00s\x00\x00\x00u\x00\x00\x00x\x00\x00\x00'
>>>

aliases.py
    # utf_8 codec
    'u8'                        : 'utf_8',
    'utf'                        : 'utf_8',
    'utf8'                      : 'utf_8',
    'utf8_ucs2'           : 'utf_8',
    'utf8_ucs4'           : 'utf_8',
    'ubom'                  : 'utf_8_sig'


So of course my favorite is u8 - less typing, and ubom for decoding if I
get those funny bytes ;')

-- 
Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From lac at openend.se  Sat Apr 25 10:20:51 2015
From: lac at openend.se (Laura Creighton)
Date: Sat, 25 Apr 2015 10:20:51 +0200
Subject: [Tutor] Introductory questions on test-driven development and
	implementing Git version control.
In-Reply-To: Message from boB Stepp <robertvstepp@gmail.com> of "Fri,
 24 Apr 2015 20:24:38 -0500."
 <CANDiX9LY7nF7g0iezmmHmoptgMgDrFKxic=pbt8qgUntYTsXbg@mail.gmail.com>
References: <robertvstepp@gmail.com>
 <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
 <201504242000.t3OK0OoB001036@fido.openend.se><CANDiX9LY7nF7g0iezmmHmoptgMgDrFKxic=pbt8qgUntYTsXbg@mail.gmail.com>
Message-ID: <201504250820.t3P8KplL021923@fido.openend.se>

In a message of Fri, 24 Apr 2015 20:24:38 -0500, boB Stepp writes:
>I have joined!

Great! Great!

>The Python versions at work are 2.4.4 and 2.6.4(?)(Not certain about
>the last digit there.) Based on responses to date, the fact that
>unittest is in the standard library and that because of this most of
>my books have something about unittest, I will probably start there. I
>imagine that everything I learn with unittest will transfer over to
>other testing frameworks.

What is even better, should you wake up one morning and decide that
you really want pytest, I written have a script that automatically converts
unittests to pytest tests.  It is included with the pytest distribution.

>> Are you absolutely certain that you cannot install git on your bare-bones
>> Solaris 10 environments?  Or plug in a memory stick and run code from
>> there?  Because it would make your life so much easier ...
>
>I think that I can get an exception here (See a post in response that
>I made earlier today.). What I am *certain* of, is that I cannot
>install anything on our clinical planning environment. The Solaris
>workstation that I now have all to myself--I'm thinking they will now
>let me do what I want with it. But I must double check... But anything
>I develop there *should* work in the clinical environment. The
>planning software is the same though that may change soon as there are
>plans to go up a version and they may not want to do that on my
>testing/development machine.

This thought 'if it works here, it ought to work there' is an unworthy
thought for somebody who has learned to test their code. ;)  You go to your
new machine.  You pull down your tests and your code.  You run all your
tests.  When they pass, you don't just _think_ that the code _ought to_
run here -- you _know_ the code will run because it passes all its tests.

This sort of peace of mind is better than money in the bank.

And, when they don't you are saved infinite amounts of embarassment.
The code  blows up _now_, when you are looking for problems, rather
than in the middle of showing off your code to some important, influential
person, because of tiny incompatibilities between what you have at home
and what you have in the field.  You can overcome, but never un-make a
bad first impression ...

So we have got to find you a way that works to get your tests and a way
to run them on your production machines.

Is there a way to stick a memory stick into these machines?  Can you
mount a filesystem there and cd to it?  Over at the university here, I
teach classes for the general public -- my buddies at the university
let me use their machines for free.  I am teaching children who don't
own a computer how to make games that run on their android cell phones --
or rather, we are all teaching each other, because I am very new to this
as well.  So they need a machine where they can do their development,
because developing on your cell phone is painful beyond belief.

Every Monday morning, and more often if they feel like it,
the university admins reset every computer to it's pristine 'just out
of the box' state.  (well, the password file will stay, but you get
the idea.) Any files you leave on the machine will be removed.  This
is to cut down on the rate of virus infection at the university, for
the most part.  So we keep all the code we care about on our memory
sticks, indeed in a virtualenv on our memory sticks.  Solaris has
virtualenv -- I checked -- see
http://www.opencsw.org/packages/CSWpy-virtualenv/

So, right now, aside from a mandate from on high that people who
plug memory sticks into their computers shall be boiled in oil, or
the situation where your machines don't have any external ports at all,
I cannot see why this solution wouldn't work for you.

See any problems with this idea I missed?

Laura


From steve at pearwood.info  Sat Apr 25 13:27:55 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 25 Apr 2015 21:27:55 +1000
Subject: [Tutor] name shortening in a csv module output
In-Reply-To: <201504241104.t3OB4vvt017540@fido.openend.se>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
 <201504241104.t3OB4vvt017540@fido.openend.se>
Message-ID: <20150425112751.GF5663@ando.pearwood.info>

On Fri, Apr 24, 2015 at 01:04:57PM +0200, Laura Creighton wrote:
> In a message of Fri, 24 Apr 2015 12:46:20 +1000, "Steven D'Aprano" writes:
> >The Japanese, Chinese and Korean 
> >governments, as well as linguists, are all in agreement that despite a 
> >few minor differences, the three languages share a common character set.
> 
> I don't think that is quite the way to say it.  There are characters,
> which look exactly the same in all three languages, and the linguists
> are mostly in agreement that the reason they look the same is that the
> are the same.
> 
> But it is more usual to write Korean, these days, not with Chinese
> characters, (hanja) but with hangul.  In the 15th century, the King,
> Sejong the great decided that Koreans needed a phoenetic alphabet, and
> made one.   It doesn't look anything like chinese.  And it is a phonetic,
> alphabetic langauge, not a stroke-and-character one.

Thanks for the correction Laura, I didn't know that Korean has two 
separate writing systems. But I did know that Japanese has at least two, 
one based on Chinese characters and the other not, and that Chinese 
itself has traditional and simplified versions of their characters. 
Beyond that, it's all Greek to me :-)


-- 
Steve

From eryksun at gmail.com  Sat Apr 25 14:48:06 2015
From: eryksun at gmail.com (eryksun)
Date: Sat, 25 Apr 2015 07:48:06 -0500
Subject: [Tutor] sig no matter what
In-Reply-To: <CALRAYNXS5FWUuACquaT2BZja-oK0JkPGzbVVWzW8LaDuCAkA1w@mail.gmail.com>
References: <CALRAYNVGiqTW72HF8g399RjJgqUg+zjoS0ZThsEvvFRfDzFEpQ@mail.gmail.com>
 <CACL+1auQaG3R4-J=B5CbXkSNaGw_-KwxuK7xMCFozXfCiyMNqg@mail.gmail.com>
 <CALRAYNXS5FWUuACquaT2BZja-oK0JkPGzbVVWzW8LaDuCAkA1w@mail.gmail.com>
Message-ID: <CACL+1at+xGqJ0TDNy0k4jzZ7Ae4nh7NqfruvrF-QehmYTA2uxA@mail.gmail.com>

On Fri, Apr 24, 2015 at 10:46 PM, Jim Mooney <cybervigilante at gmail.com> wrote:
> The docs don't mention that case is immaterial for aliases, when it usually
> matters in Python.

Section 7.2.3:

    Notice that spelling alternatives that only differ in case or use a hyphen
    instead of an underscore are also valid aliases

> So of course my favorite is u8 - less typing, and ubom for decoding if I get
> those funny bytes ;')

Less typing, yes, but also less self-documenting.

From jon.engle at gmail.com  Sat Apr 25 15:46:26 2015
From: jon.engle at gmail.com (Juanald Reagan)
Date: Sat, 25 Apr 2015 09:46:26 -0400
Subject: [Tutor] whois github package
Message-ID: <CAOpmNVHO=6GU2doxq2c8kcKyb8qQ9jcPMUZT9_VU+7x8V9TTsQ@mail.gmail.com>

Hello! I have a question regarding how to use/implement a package found at
github.

https://github.com/secynic/ipwhois

I am able to run the sample code without any issues but what I don't
understand is how to put all the data that is returned into an indexed
list. I want to be able to pick out some of the returned data through an
index.

For example:

    from ipwhois import IPWhois

    obj = IPWhois(ipaddy)
    results = [obj.lookup()]
    print results [0]

This returns ALL the fields not just the "asn_registry" field. I looked for
documentation on github but did not see anything. Any thoughts/comments are
appreciated, thanks!

-- 
Cheers,

   Jon

From steve at pearwood.info  Sat Apr 25 16:13:39 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Apr 2015 00:13:39 +1000
Subject: [Tutor] whois github package
In-Reply-To: <CAOpmNVHO=6GU2doxq2c8kcKyb8qQ9jcPMUZT9_VU+7x8V9TTsQ@mail.gmail.com>
References: <CAOpmNVHO=6GU2doxq2c8kcKyb8qQ9jcPMUZT9_VU+7x8V9TTsQ@mail.gmail.com>
Message-ID: <20150425141338.GG5663@ando.pearwood.info>

On Sat, Apr 25, 2015 at 09:46:26AM -0400, Juanald Reagan wrote:

>     from ipwhois import IPWhois
> 
>     obj = IPWhois(ipaddy)
>     results = [obj.lookup()]
>     print results [0]
> 
> This returns ALL the fields not just the "asn_registry" field. I looked for
> documentation on github but did not see anything. Any thoughts/comments are
> appreciated, thanks!

I don't have ipwhois installed, so I'm guessing, but try this:


obj = IPWhois(ipaddy)
results = obj.lookup()
print results.asn_registry

If that doesn't work, please copy and paste the entire traceback, and 
then run this and show us the result:

vars(results)




-- 
Steve

From robertvstepp at gmail.com  Sat Apr 25 17:30:02 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 25 Apr 2015 10:30:02 -0500
Subject: [Tutor] Questions (and initial responses) on using version control
 [Was: Introductory questions on test-driven development and implementing
 Git version control.]
Message-ID: <CANDiX9JCMPoWNZFaFJO+_amZU+KKdMcxa9+imrwYjp=4diYR0A@mail.gmail.com>

N.B.: This is a manual recreation of portions of the original thread,
"Introductory questions on test-driven development and implementing
Git version control". The portions included here are those relevant to
the version control. Where "[...]" appears, this indicates I did not
include those portions of the original thread here.

In a message of Fri, 24 Apr 2015 14:09:45 -0500, boB Stepp writes:

[...]

>My wife (A teacher.) has been after me a lot lately to write some
>programs to make her teaching life better. So I would like to start
>one of her projects using TDD from the get-go. Also, this sounds like
>a good time to try to implement using version control software. While
>setting up Vim recently, I had to install Git (In order to get Vundle
>going.). So now I have that to play with. And to throw more fuel onto
>the fire of learning, why not jump into OOP for this project as well?
>It's about time! Plus it will make life with Tkinter a bit better,
>too.

>The project(s) will be coded in Python 3.4 on Windows 7 64-bit on my
>home computer. All projects that I actually complete for my wife will
>be implemented in her classroom, which has quite a variety of hardware
>and OS platforms: lap tops and desk tops, some of which are rather
>old, running Windows XP, Windows 7, and Ubuntu Linux. And possibly
>other combos that I have not been made aware of yet.

[...]

>And what would be the best approach to integrating Git with these
>efforts? Just how often does one commit one's code to the version
>control system? Or do I have some GCEs (Gross Conceptual Errors) here?
>Can Git be set up to automatically keep track of my code as I create
>and edit it?

[...]

>And I would like to have all of that under version control, too. But
>while I am allowed to write my own programs for this CSA, I am not
>allowed to install anything else, strange as this may sound! Since the
>only functional editors in these bare-bones Solaris 10 environments
>are some simplistic default editor that I do not know the name of and
>vi, I long ago gravitated to doing my actual coding on my Windows PC
>(Being careful to save things with Unix line endings.) and FTPing to
>the environments where these programs will actually run. I AM allowed
>to install anything I want (within reason)on my PC. So I am thinking
>install and use Git there?
----------------------------------------------------------------------
In a message of Fri, 24 Apr 2015 at 3:00 PM, Laura Creighton writes:

>In a message of Fri, 24 Apr 2015 14:09:45 -0500, boB Stepp writes:

[...]

>>And what would be the best approach to integrating Git with these
>>efforts? Just how often does one commit one's code to the version
>>control system? Or do I have some GCEs (Gross Conceptual Errors) here?
>>Can Git be set up to automatically keep track of my code as I create
>>and edit it?

>Depending on what you mean by that, the answer is 'no' or 'that is
>exactly what git does, there is no way to _prevent_ this'.

>You have to tell git when you would like to save your work.
>It doesn't work like autosaving in an editor -- hah hah, she has typed
>300 chars now,  (or it has been 5 minutes now) time to autosave -- if
>you never tell git to save the work, it will never get saved.

>So what you typically do is write a test, tell git to save it, run the
>test, have it fail, write some more code and run  all the tests again,
>have them pass, tell git to save it, write another test ...

>If in the 'write some more code' part, you get the itch 'it would be
>really bad if my laptop died and I lost all this work' you tell git to
>save immediately and keep on going.

>There is a whole other layer about 'how to share your code with other
>people, politely, when several of you are working on the same project
>at one time, but if you are a one man team, you won't have to worry
>about that for a while.

[...]

>>And I would like to have all of that under version control, too. But
>>while I am allowed to write my own programs for this CSA, I am not
>>allowed to install anything else, strange as this may sound! Since the
>>only functional editors in these bare-bones Solaris 10 environments
>>are some simplistic default editor that I do not know the name of and
>>vi, I long ago gravitated to doing my actual coding on my Windows PC
>>(Being careful to save things with Unix line endings.) and FTPing to
>>the environments where these programs will actually run. I AM allowed
>>to install anything I want (within reason)on my PC. So I am thinking
>>install and use Git there?

>Are you absolutely certain that you cannot install git on your bare-bones
>Solaris 10 environments?  Or plug in a memory stick and run code from
>there?  Because it would make your life so much easier ...
----------------------------------------------------------------------
On Fri., Apr 24, 2015 at 5:03 PM Alan Gauld wrote:

>On 24/04/15 20:09, boB Stepp wrote:

[...]

>> allowed to install anything else, strange as this may sound! Since the
>> only functional editors in these bare-bones Solaris 10 environments
>> are some simplistic default editor that I do not know the name of and
>> vi,

[...]

>And of course it has the original SCCS for source control.
>Which if there's only a few of you is adequate, and easy
>to work with. I used SCCS on several major projects over
>a 10 year period.
----------------------------------------------------------------------
On Fri, Apr 24, 2015 at 5:52 PM, boB Stepp wrote:
>On Fri, Apr 24, 2015 at 5:03 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:

[...]

>> And of course it has the original SCCS for source control.
>> Which if there's only a few of you is adequate, and easy
>> to work with. I used SCCS on several major projects over
>> a 10 year period.

>There is just lil ol' me. I will have to research SCCS.
----------------------------------------------------------------------
On Fri, Apr 24, 2015 at 7:36 PM, Steven D'Aprano wrote:
>On Fri, Apr 24, 2015 at 02:09:45PM -0500, boB Stepp wrote:

[...]

>> And what would be the best approach to integrating Git with these
>> efforts? Just how often does one commit one's code to the version
>> control system? Or do I have some GCEs (Gross Conceptual Errors) here?
>> Can Git be set up to automatically keep track of my code as I create
>> and edit it?

>No, that's not how revision control works. You really don't want every
>time you hit save to count as a new revision. That would be ugly.

>Joel Spolsky has a good introduction to Mercurial (hg). Git is slightly
>different, but the fundamentals are more or less equivalent:

>http://hginit.com/
?
>You can also watch Git For Ages 4 And Up:

>http://www.youtube.com/watch?v=1ffBJ4sVUb4


>The executive summary of how I use version control:

>- work on bite-sized chunks of functionality
>- when the tests all pass, commit the work done
>- push changes to the master repo at least once per day


>The way I use version control on my own is that I have typically use a
>single branch. I rarely have to worry about contributions from others,
>so it's just my changes. Make sure that all the relevent files (source
>code, documentation, tests, images, etc.) are being tracked. Static
>files which never change, like reference materials, should not be.

>Starting from a point where all the tests pass, I decide to work on a
>new feature, or fix a bug. A feature might be something as small as "fix
>the documentation for this function", but *not* as big as "control
>remote controlled space ship" -- in other words, a bite-sized chunk of
>work, not a full meal. I write some tests, and write the minimal amount
>of code code that makes those tests pass:

>- write tests
>- save tests
>- write code
>- save code
>- run tests
>- fix bugs in tests
>- save tests
>- write some more code
>- save code
>- run tests again
>- write some more code
>- save code
>- run tests again


>etc. Once the tests pass, then I have a feature and/or bug fix, and I
>commit all the relevent changes to the VCS. hg automatically tracks
>files, git requires you to remind it every single time what files are
>being used, but either way, by the time I run `hg commit` or `git
>commit` I have a complete, and hopefully working, bite-sized chunk of
>code that has an obvious commit message:

>"fix bug in spam function"
>"correct spelling errors in module docs"
>"rename function ham to spam"
>"change function eggs from using a list to a dict"
>"move class K into its own submodule"

>etc. Notice that each change is small enough to encapsulate in a short
>description, but big enough that some of them may require multiple
>rounds of back-and-forth code-and-test before it works.

>I run the tests even after seemingly innoculous changes to comments or
>docstrings, especially docstrings. Edits to a docstring may break your
>doctests, or even your code, if you accidentally break the quoting.

>Then, when I am feeling satisfied that I've done a sufficiently large
>amount of work, I then push those changes to the master repo (if any).
>This allows me to work from various computers and still share the same
>code base. "Sufficiently large" may mean a single change, or a full
>day's work, or a whole lot of related changes that add up to one big
>change, whatever you prefer. But it shouldn't be less than once per day.

[...]

>> And I would like to have all of that under version control, too. But
>> while I am allowed to write my own programs for this CSA, I am not
>> allowed to install anything else, strange as this may sound! Since the
>> only functional editors in these bare-bones Solaris 10 environments
>> are some simplistic default editor that I do not know the name of and
>> vi, I long ago gravitated to doing my actual coding on my Windows PC
>> (Being careful to save things with Unix line endings.) and FTPing to
>> the environments where these programs will actually run. I AM allowed
>> to install anything I want (within reason)on my PC. So I am thinking
>> install and use Git there?

>Yes.
----------------------------------------------------------------------
On Fri, Apr 24, 2015 at 7:46 PM, Alan Gauld wrote:
>On 24/04/15 23:52, boB Stepp wrote:

>> There is just lil ol' me. I will have to research SCCS.


>SCCS is great for a single, small team. It's marginally more complex
>than more modern tools and it only works sensibly with text files
>(binaries are just uuencoded which is pretty pointless!).

>Basic usage is very simple:
>1) create an SCCS directory in your project space - or you wind up
>   with version files all over the place!
>2) use the admin -i command to tell sccs to manage a file
>3) use get to get a read only copy or get -e to get an editable one.
>   (use -r to get a specific version)
>4) use delta to save changes (it prompts you for change comments etc)

>There are a bunch of other reporting and searching and admin
>commands, but the above is all you need 90% of the time.
>More modern versioning systems are better but SCCS should already
>be installed on Solaris 10 if you have the development tools
>installed, which I'm guessing you do or pretty much
>nothing code-wise would work.
----------------------------------------------------------------------
On Fri, Apr 24, 2015 at 8:24 PM, boB Stepp wrote:
>On Fri, Apr 24, 2015 at 3:00 PM, Laura Creighton <lac at openend.se> wrote:
>> In a message of Fri, 24 Apr 2015 14:09:45 -0500, boB Stepp writes:

[...]

>>>And I would like to have all of that under version control, too. But
>>>while I am allowed to write my own programs for this CSA, I am not
>>>allowed to install anything else, strange as this may sound! Since the
>>>only functional editors in these bare-bones Solaris 10 environments
>>>are some simplistic default editor that I do not know the name of and
>>>vi, I long ago gravitated to doing my actual coding on my Windows PC
>>>(Being careful to save things with Unix line endings.) and FTPing to
>>>the environments where these programs will actually run. I AM allowed
>>>to install anything I want (within reason)on my PC. So I am thinking
>>>install and use Git there?
>>
>> Are you absolutely certain that you cannot install git on your bare-bones
>> Solaris 10 environments?  Or plug in a memory stick and run code from
>> there?  Because it would make your life so much easier ...

>I think that I can get an exception here (See a post in response that
>I made earlier today.). What I am *certain* of, is that I cannot
>install anything on our clinical planning environment. The Solaris
>workstation that I now have all to myself--I'm thinking they will now
>let me do what I want with it. But I must double check... But anything
>I develop there *should* work in the clinical environment. The
>planning software is the same though that may change soon as there are
>plans to go up a version and they may not want to do that on my
>testing/development machine.
----------------------------------------------------------------------

From robertvstepp at gmail.com  Sat Apr 25 17:34:59 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 25 Apr 2015 10:34:59 -0500
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <mhfiqf$a95$1@ger.gmane.org>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
 <mhfiqf$a95$1@ger.gmane.org>
Message-ID: <CANDiX9LamJBA0zb8K4B42kMvjyJyqGeHC=Lth9hTbVYf-+cpng@mail.gmail.com>

On Sat, Apr 25, 2015 at 3:21 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> Having looked at this thread and its early responses I think it
> would be good to break it up into its two natural parts. TDD
> and version control are pretty much separate concepts and
> should be on separate threads.
>
> Bob, could you please ask your version control questions again,
> taking account of early responses, on a new thread? That way
> we can keep the TDD stuff together and the version control
> stuff in a separate place.

Done! I do not know if what I did matches your intent, but I hope so!
I stuffed everything relevant to version control into a single email,
trying my best to keep attributions, etc., accurate. It makes for a
long post, but it has everything nicely in place. I just hope Gmail
did not mangle anything!

In retrospect, I wish I had copied and pasted every post so far into
Vim, did my editing there, and re-copy and paste into a new email. I
keep forgetting that text is text...

-- 
boB

From akleider at sonic.net  Sat Apr 25 17:51:58 2015
From: akleider at sonic.net (Alex Kleider)
Date: Sat, 25 Apr 2015 08:51:58 -0700
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <CANDiX9LamJBA0zb8K4B42kMvjyJyqGeHC=Lth9hTbVYf-+cpng@mail.gmail.com>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
 <mhfiqf$a95$1@ger.gmane.org>
 <CANDiX9LamJBA0zb8K4B42kMvjyJyqGeHC=Lth9hTbVYf-+cpng@mail.gmail.com>
Message-ID: <f53ac9ac2e3423caeafde4c9f6759d84@sonic.net>

On 2015-04-25 08:34, boB Stepp wrote:
> On Sat, Apr 25, 2015 at 3:21 AM, Alan Gauld <alan.gauld at btinternet.com> 
> wrote:
>> Having looked at this thread and its early responses I think it
>> would be good to break it up into its two natural parts. TDD
>> and version control are pretty much separate concepts and
>> should be on separate threads.
>> 
>> Bob, could you please ask your version control questions again,
>> taking account of early responses, on a new thread? That way
>> we can keep the TDD stuff together and the version control
>> stuff in a separate place.
> 
> Done! I do not know if what I did matches your intent, but I hope so!
> I stuffed everything relevant to version control into a single email,
> trying my best to keep attributions, etc., accurate. It makes for a
> long post, but it has everything nicely in place. I just hope Gmail
> did not mangle anything!
> 
> In retrospect, I wish I had copied and pasted every post so far into
> Vim, did my editing there, and re-copy and paste into a new email. I
> keep forgetting that text is text...

This might be of interest to you:
https://addons.mozilla.org/en-us/firefox/addon/its-all-text/


From robertvstepp at gmail.com  Sat Apr 25 17:58:14 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 25 Apr 2015 10:58:14 -0500
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <201504250820.t3P8KplL021923@fido.openend.se>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
 <201504242000.t3OK0OoB001036@fido.openend.se>
 <robertvstepp@gmail.com>
 <CANDiX9LY7nF7g0iezmmHmoptgMgDrFKxic=pbt8qgUntYTsXbg@mail.gmail.com>
 <201504250820.t3P8KplL021923@fido.openend.se>
Message-ID: <CANDiX9KFMNsb8dL56OzxShS_JKny4we1RQKmVg2Jf+BJwpqL0A@mail.gmail.com>

On Sat, Apr 25, 2015 at 3:20 AM, Laura Creighton <lac at openend.se> wrote:
> In a message of Fri, 24 Apr 2015 20:24:38 -0500, boB Stepp writes:

>>The Python versions at work are 2.4.4 and 2.6.4(?)(Not certain about
>>the last digit there.) Based on responses to date, the fact that
>>unittest is in the standard library and that because of this most of
>>my books have something about unittest, I will probably start there. I
>>imagine that everything I learn with unittest will transfer over to
>>other testing frameworks.
>
> What is even better, should you wake up one morning and decide that
> you really want pytest, I written have a script that automatically converts
> unittests to pytest tests.  It is included with the pytest distribution.

This is very good to know!

>>> Are you absolutely certain that you cannot install git on your bare-bones
>>> Solaris 10 environments?  Or plug in a memory stick and run code from
>>> there?  Because it would make your life so much easier ...

On your original post this did not register in my brain properly. This
might be possible. The thin clients that hook us to Smart Enterprise
*do* have a couple of USB ports. I know that they are functional as I
watched the installer using one. I will have to investigate this!

>>I think that I can get an exception here (See a post in response that
>>I made earlier today.). What I am *certain* of, is that I cannot
>>install anything on our clinical planning environment. The Solaris
>>workstation that I now have all to myself--I'm thinking they will now
>>let me do what I want with it. But I must double check... But anything
>>I develop there *should* work in the clinical environment. The
>>planning software is the same though that may change soon as there are
>>plans to go up a version and they may not want to do that on my
>>testing/development machine.
>
> This thought 'if it works here, it ought to work there' is an unworthy
> thought for somebody who has learned to test their code. ;)  You go to your
> new machine.  You pull down your tests and your code.  You run all your
> tests.  When they pass, you don't just _think_ that the code _ought to_
> run here -- you _know_ the code will run because it passes all its tests.

You have a very gentle way of chastising me! ~(:>))

I *do* test when I transfer code to the production environment, but to
date these have all been manual. And the whole point here is for me to
learn how to do full-fledged automated testing. And if there is ever a
place to ensure I do this, it is in the production environment! But I
did not see how to make it work there. Perhaps the memory stick idea
or Alan's SCCS can get around these difficulties.

> So we have got to find you a way that works to get your tests and a way
> to run them on your production machines.
>
> Is there a way to stick a memory stick into these machines?  Can you
> mount a filesystem there and cd to it?...

As I said above, I will see if this is doable. The ports exist, but
are they usable?

> ...So we keep all the code we care about on our memory
> sticks, indeed in a virtualenv on our memory sticks.  Solaris has
> virtualenv -- I checked -- see
> http://www.opencsw.org/packages/CSWpy-virtualenv/

I have only messed around with a virtual environment once a few years
ago for some project at home that I no longer recall the details for.
I did not get very deeply into understanding things, so I would have
some learning curve here.

On a different testing-related note, I have read that it is a good
idea sometimes to do one's code testing within the confines of a
virtual environment for safety reasons, particularly if some code
comes from outside sources? Would you mind speaking to that topic?

> So, right now, aside from a mandate from on high that people who
> plug memory sticks into their computers shall be boiled in oil, or
> the situation where your machines don't have any external ports at all,
> I cannot see why this solution wouldn't work for you.

There might be some who would enjoy doing this! ~(:>))

IS is a bit sensitive about the use of memory sticks. We have had
multiple instances of virus infections via this route, often from
people who really should have known better. But I am pleased to report
I have not been one of them! (Keeping fingers crossed, knocking on
wood, etc.)

-- 
boB

From alan.gauld at btinternet.com  Sat Apr 25 18:19:31 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 25 Apr 2015 17:19:31 +0100
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <CANDiX9LamJBA0zb8K4B42kMvjyJyqGeHC=Lth9hTbVYf-+cpng@mail.gmail.com>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
 <mhfiqf$a95$1@ger.gmane.org>
 <CANDiX9LamJBA0zb8K4B42kMvjyJyqGeHC=Lth9hTbVYf-+cpng@mail.gmail.com>
Message-ID: <mhgeqg$lo6$1@ger.gmane.org>

On 25/04/15 16:34, boB Stepp wrote:

> Done! I do not know if what I did matches your intent, but I hope so!

You've done much more than I intended. I only wanted you to consider 
what has already been said then re-frame any remaining VC questions in
a new mail. But no harm done except for your time.

Thanks.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Sat Apr 25 19:40:16 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 25 Apr 2015 18:40:16 +0100
Subject: [Tutor] Questions (and initial responses) on using version
 control [Was: Introductory questions on test-driven development and
 implementing Git version control.]
In-Reply-To: <CANDiX9JCMPoWNZFaFJO+_amZU+KKdMcxa9+imrwYjp=4diYR0A@mail.gmail.com>
References: <CANDiX9JCMPoWNZFaFJO+_amZU+KKdMcxa9+imrwYjp=4diYR0A@mail.gmail.com>
Message-ID: <mhgjht$vn6$1@ger.gmane.org>

On 25/04/15 16:30, boB Stepp wrote:

>> And what would be the best approach to integrating Git with these
>> efforts? Just how often does one commit one's code to the version
>> control system? Or do I have some GCEs (Gross Conceptual Errors) here?

Going back to first principles.
What is often called Version Control or Configuration Management
actually encompasses two distinct disciplines:
1) File versioning
2) Release management

File versioning is where you save multiple versions of files as
you go so that you can revert to a previous version. This could
be because you've made some bad changes that you want to back
out or it could be because you have a production version that
is not current and it has developed a bug. It also supports
branching which is where you develop parallel streams of
development. This could be to support different platforms etc.
Its also an important tool to manage multiple developers working
on the same files - but that is less of an issue for you.

Release management is about organising groups of files into
releases and versioning the whole release. Thus release 1.0
contains:
v1.4 of File A
v3.7 of FileB
v2.2 of Fi;le C
and so on.
A release should ideally also keep the toolset with which
the release was created (older compiler versions/OS etc) but
often that is simply stored as a text file with the necessary
details recorded.

That way you can call up release 1 at any time. As with files
you may have branched parallel developments of releases as well
as individual files. For example you may have 2 production
releases, a system test release and one or more development
releases active at any time. You may need to recreate any
of those releases at any given moment.

So, to decide what to do about Config Mgt you need to decide
whether you want to focus on version control or release control?
Or both. The tools tend to be focused on one or the other.

If you are just starting out I'd recommend a basic version
control setup because its much simpler and you can use the
reporting tools and batch files to manually handle releases
initially. If you do a lot of releases with multiple files
then you should maybe jump into a release capable tool right
away.

CM tools are like editors and they tend to have rabid supporters.
I've used over a dozen of them over the years, mostly commercial
and many costing thousands of dollars, but there are capable open
source ones nowadays that can certainly do all that you want.
Many of the modern tools are focussed on multi-developer, parallel, 
distributed, developments; as is typical of open source projects.
If you are a small team/individual working on a single
release stream in a single site things are much simpler.

My experience in that area is limited to SCCS/RCS for file based version 
control and CVS and SVN for release management. But my needs are fairly 
simple...

Also many tools can be integrated with editors like Eclipse,
Netbeans, Visual Studio, emacs and vim. This makes basic functions
much easier to use - literally a mouse click away.

But the first decision is what exactly do you want to use the
tool for?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From cybervigilante at gmail.com  Sat Apr 25 16:56:26 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sat, 25 Apr 2015 07:56:26 -0700
Subject: [Tutor] Codec lookup,
	was Re: name shortening in a csv module output
In-Reply-To: <mhfipo$9v7$1@ger.gmane.org>
References: <CALRAYNXwfOOSgv6-GC6FHf-wAOxXKv1J3CHYD1=hDdcg8SnC3A@mail.gmail.com>
 <mhaba6$gvd$1@ger.gmane.org>
 <CALRAYNV6naA2z7YKWAQ8JD4rK9fXrDavAs7PdnQa730vK=qPXQ@mail.gmail.com>
 <553901D6.90006@davea.name>
 <CALRAYNVCkVrV4N58rbrV3xL_1Xnk=ALnjpFKAQmOJUkiwSGoUQ@mail.gmail.com>
 <mhbn2s$6ck$1@ger.gmane.org>
 <CALRAYNXNxbgs6=eT3H0Tw52+123BHRarrdhJ+zY5bXubq5B9sA@mail.gmail.com>
 <20150424100800.GV5663@ando.pearwood.info>
 <CALRAYNVgRavwep95VfDjqsTz6yCVQgtrdsdpXfat_bDGFZfCyQ@mail.gmail.com>
 <20150425005029.GD5663@ando.pearwood.info>
 <mhfipo$9v7$1@ger.gmane.org>
Message-ID: <CALRAYNXBsdzpBGjXqsWqt3tLgT+tj5VF5wah740954Nkjco9nA@mail.gmail.com>

>
> Hm, who the heck uses "u8"? I'd rather go with
>
> >>> encodings.aliases.aliases["steven_s_preferred_encoding"] = "utf_8"
> >>> "Hello".encode("--- Steven's preferred encoding ---")
> b'Hello'
>
> ;)
>

Peter Otten

> __
>

Or normalize almost any mistyping ;'):

>>> encodings.normalize_encoding('utf&&$%##8')
'utf_8'

-- 
Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From jon.engle at gmail.com  Sat Apr 25 20:13:50 2015
From: jon.engle at gmail.com (Juanald Reagan)
Date: Sat, 25 Apr 2015 14:13:50 -0400
Subject: [Tutor] Tutor Digest, Vol 134, Issue 86
In-Reply-To: <mailman.399.1429975810.3679.tutor@python.org>
References: <mailman.399.1429975810.3679.tutor@python.org>
Message-ID: <CAOpmNVEoS06FaTHnZSx2KwZiMku41rmXQVb82D3r9nvceGXGGw@mail.gmail.com>

Okay, so it doesn't look like that worked...here is the traceback. I don't
understand the second part of your request.

Jons-desktop:whois-0.7 2 jon$ python pythonwhois.py

8.8.8.8

Traceback (most recent call last):

  File "pythonwhois.py", line 14, in <module>

    print results.asn_registry

AttributeError: 'dict' object has no attribute 'asn_registry'



On Sat, Apr 25, 2015 at 11:30 AM, <tutor-request at python.org> wrote:

> Send Tutor mailing list submissions to
>         tutor at python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://mail.python.org/mailman/listinfo/tutor
> or, via email, send a message with subject or body 'help' to
>         tutor-request at python.org
>
> You can reach the person managing the list at
>         tutor-owner at python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Tutor digest..."
>
>
> Today's Topics:
>
>    1. Re: name shortening in a csv module output (Steven D'Aprano)
>    2. Re: sig no matter what (eryksun)
>    3. whois github package (Juanald Reagan)
>    4. Re: whois github package (Steven D'Aprano)
>    5. Questions (and initial responses) on using version control
>       [Was: Introductory questions on test-driven development and
>       implementing Git version control.] (boB Stepp)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Sat, 25 Apr 2015 21:27:55 +1000
> From: Steven D'Aprano <steve at pearwood.info>
> To: tutor at python.org
> Subject: Re: [Tutor] name shortening in a csv module output
> Message-ID: <20150425112751.GF5663 at ando.pearwood.info>
> Content-Type: text/plain; charset=us-ascii
>
> On Fri, Apr 24, 2015 at 01:04:57PM +0200, Laura Creighton wrote:
> > In a message of Fri, 24 Apr 2015 12:46:20 +1000, "Steven D'Aprano"
> writes:
> > >The Japanese, Chinese and Korean
> > >governments, as well as linguists, are all in agreement that despite a
> > >few minor differences, the three languages share a common character set.
> >
> > I don't think that is quite the way to say it.  There are characters,
> > which look exactly the same in all three languages, and the linguists
> > are mostly in agreement that the reason they look the same is that the
> > are the same.
> >
> > But it is more usual to write Korean, these days, not with Chinese
> > characters, (hanja) but with hangul.  In the 15th century, the King,
> > Sejong the great decided that Koreans needed a phoenetic alphabet, and
> > made one.   It doesn't look anything like chinese.  And it is a phonetic,
> > alphabetic langauge, not a stroke-and-character one.
>
> Thanks for the correction Laura, I didn't know that Korean has two
> separate writing systems. But I did know that Japanese has at least two,
> one based on Chinese characters and the other not, and that Chinese
> itself has traditional and simplified versions of their characters.
> Beyond that, it's all Greek to me :-)
>
>
> --
> Steve
>
>
> ------------------------------
>
> Message: 2
> Date: Sat, 25 Apr 2015 07:48:06 -0500
> From: eryksun <eryksun at gmail.com>
> To: "tutor at python.org" <tutor at python.org>
> Subject: Re: [Tutor] sig no matter what
> Message-ID:
>         <
> CACL+1at+xGqJ0TDNy0k4jzZ7Ae4nh7NqfruvrF-QehmYTA2uxA at mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> On Fri, Apr 24, 2015 at 10:46 PM, Jim Mooney <cybervigilante at gmail.com>
> wrote:
> > The docs don't mention that case is immaterial for aliases, when it
> usually
> > matters in Python.
>
> Section 7.2.3:
>
>     Notice that spelling alternatives that only differ in case or use a
> hyphen
>     instead of an underscore are also valid aliases
>
> > So of course my favorite is u8 - less typing, and ubom for decoding if I
> get
> > those funny bytes ;')
>
> Less typing, yes, but also less self-documenting.
>
>
> ------------------------------
>
> Message: 3
> Date: Sat, 25 Apr 2015 09:46:26 -0400
> From: Juanald Reagan <jon.engle at gmail.com>
> To: "tutor at python.org" <tutor at python.org>
> Subject: [Tutor] whois github package
> Message-ID:
>         <CAOpmNVHO=
> 6GU2doxq2c8kcKyb8qQ9jcPMUZT9_VU+7x8V9TTsQ at mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> Hello! I have a question regarding how to use/implement a package found at
> github.
>
> https://github.com/secynic/ipwhois
>
> I am able to run the sample code without any issues but what I don't
> understand is how to put all the data that is returned into an indexed
> list. I want to be able to pick out some of the returned data through an
> index.
>
> For example:
>
>     from ipwhois import IPWhois
>
>     obj = IPWhois(ipaddy)
>     results = [obj.lookup()]
>     print results [0]
>
> This returns ALL the fields not just the "asn_registry" field. I looked for
> documentation on github but did not see anything. Any thoughts/comments are
> appreciated, thanks!
>
> --
> Cheers,
>
>    Jon
>
>
> ------------------------------
>
> Message: 4
> Date: Sun, 26 Apr 2015 00:13:39 +1000
> From: Steven D'Aprano <steve at pearwood.info>
> To: tutor at python.org
> Subject: Re: [Tutor] whois github package
> Message-ID: <20150425141338.GG5663 at ando.pearwood.info>
> Content-Type: text/plain; charset=us-ascii
>
> On Sat, Apr 25, 2015 at 09:46:26AM -0400, Juanald Reagan wrote:
>
> >     from ipwhois import IPWhois
> >
> >     obj = IPWhois(ipaddy)
> >     results = [obj.lookup()]
> >     print results [0]
> >
> > This returns ALL the fields not just the "asn_registry" field. I looked
> for
> > documentation on github but did not see anything. Any thoughts/comments
> are
> > appreciated, thanks!
>
> I don't have ipwhois installed, so I'm guessing, but try this:
>
>
> obj = IPWhois(ipaddy)
> results = obj.lookup()
> print results.asn_registry
>
> If that doesn't work, please copy and paste the entire traceback, and
> then run this and show us the result:
>
> vars(results)
>
>
>
>
> --
> Steve
>
>
> ------------------------------
>
> Message: 5
> Date: Sat, 25 Apr 2015 10:30:02 -0500
> From: boB Stepp <robertvstepp at gmail.com>
> To: tutor <tutor at python.org>
> Subject: [Tutor] Questions (and initial responses) on using version
>         control [Was: Introductory questions on test-driven development and
>         implementing Git version control.]
> Message-ID:
>         <CANDiX9JCMPoWNZFaFJO+_amZU+KKdMcxa9+imrwYjp=
> 4diYR0A at mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> N.B.: This is a manual recreation of portions of the original thread,
> "Introductory questions on test-driven development and implementing
> Git version control". The portions included here are those relevant to
> the version control. Where "[...]" appears, this indicates I did not
> include those portions of the original thread here.
>
> In a message of Fri, 24 Apr 2015 14:09:45 -0500, boB Stepp writes:
>
> [...]
>
> >My wife (A teacher.) has been after me a lot lately to write some
> >programs to make her teaching life better. So I would like to start
> >one of her projects using TDD from the get-go. Also, this sounds like
> >a good time to try to implement using version control software. While
> >setting up Vim recently, I had to install Git (In order to get Vundle
> >going.). So now I have that to play with. And to throw more fuel onto
> >the fire of learning, why not jump into OOP for this project as well?
> >It's about time! Plus it will make life with Tkinter a bit better,
> >too.
>
> >The project(s) will be coded in Python 3.4 on Windows 7 64-bit on my
> >home computer. All projects that I actually complete for my wife will
> >be implemented in her classroom, which has quite a variety of hardware
> >and OS platforms: lap tops and desk tops, some of which are rather
> >old, running Windows XP, Windows 7, and Ubuntu Linux. And possibly
> >other combos that I have not been made aware of yet.
>
> [...]
>
> >And what would be the best approach to integrating Git with these
> >efforts? Just how often does one commit one's code to the version
> >control system? Or do I have some GCEs (Gross Conceptual Errors) here?
> >Can Git be set up to automatically keep track of my code as I create
> >and edit it?
>
> [...]
>
> >And I would like to have all of that under version control, too. But
> >while I am allowed to write my own programs for this CSA, I am not
> >allowed to install anything else, strange as this may sound! Since the
> >only functional editors in these bare-bones Solaris 10 environments
> >are some simplistic default editor that I do not know the name of and
> >vi, I long ago gravitated to doing my actual coding on my Windows PC
> >(Being careful to save things with Unix line endings.) and FTPing to
> >the environments where these programs will actually run. I AM allowed
> >to install anything I want (within reason)on my PC. So I am thinking
> >install and use Git there?
> ----------------------------------------------------------------------
> In a message of Fri, 24 Apr 2015 at 3:00 PM, Laura Creighton writes:
>
> >In a message of Fri, 24 Apr 2015 14:09:45 -0500, boB Stepp writes:
>
> [...]
>
> >>And what would be the best approach to integrating Git with these
> >>efforts? Just how often does one commit one's code to the version
> >>control system? Or do I have some GCEs (Gross Conceptual Errors) here?
> >>Can Git be set up to automatically keep track of my code as I create
> >>and edit it?
>
> >Depending on what you mean by that, the answer is 'no' or 'that is
> >exactly what git does, there is no way to _prevent_ this'.
>
> >You have to tell git when you would like to save your work.
> >It doesn't work like autosaving in an editor -- hah hah, she has typed
> >300 chars now,  (or it has been 5 minutes now) time to autosave -- if
> >you never tell git to save the work, it will never get saved.
>
> >So what you typically do is write a test, tell git to save it, run the
> >test, have it fail, write some more code and run  all the tests again,
> >have them pass, tell git to save it, write another test ...
>
> >If in the 'write some more code' part, you get the itch 'it would be
> >really bad if my laptop died and I lost all this work' you tell git to
> >save immediately and keep on going.
>
> >There is a whole other layer about 'how to share your code with other
> >people, politely, when several of you are working on the same project
> >at one time, but if you are a one man team, you won't have to worry
> >about that for a while.
>
> [...]
>
> >>And I would like to have all of that under version control, too. But
> >>while I am allowed to write my own programs for this CSA, I am not
> >>allowed to install anything else, strange as this may sound! Since the
> >>only functional editors in these bare-bones Solaris 10 environments
> >>are some simplistic default editor that I do not know the name of and
> >>vi, I long ago gravitated to doing my actual coding on my Windows PC
> >>(Being careful to save things with Unix line endings.) and FTPing to
> >>the environments where these programs will actually run. I AM allowed
> >>to install anything I want (within reason)on my PC. So I am thinking
> >>install and use Git there?
>
> >Are you absolutely certain that you cannot install git on your bare-bones
> >Solaris 10 environments?  Or plug in a memory stick and run code from
> >there?  Because it would make your life so much easier ...
> ----------------------------------------------------------------------
> On Fri., Apr 24, 2015 at 5:03 PM Alan Gauld wrote:
>
> >On 24/04/15 20:09, boB Stepp wrote:
>
> [...]
>
> >> allowed to install anything else, strange as this may sound! Since the
> >> only functional editors in these bare-bones Solaris 10 environments
> >> are some simplistic default editor that I do not know the name of and
> >> vi,
>
> [...]
>
> >And of course it has the original SCCS for source control.
> >Which if there's only a few of you is adequate, and easy
> >to work with. I used SCCS on several major projects over
> >a 10 year period.
> ----------------------------------------------------------------------
> On Fri, Apr 24, 2015 at 5:52 PM, boB Stepp wrote:
> >On Fri, Apr 24, 2015 at 5:03 PM, Alan Gauld <alan.gauld at btinternet.com>
> wrote:
>
> [...]
>
> >> And of course it has the original SCCS for source control.
> >> Which if there's only a few of you is adequate, and easy
> >> to work with. I used SCCS on several major projects over
> >> a 10 year period.
>
> >There is just lil ol' me. I will have to research SCCS.
> ----------------------------------------------------------------------
> On Fri, Apr 24, 2015 at 7:36 PM, Steven D'Aprano wrote:
> >On Fri, Apr 24, 2015 at 02:09:45PM -0500, boB Stepp wrote:
>
> [...]
>
> >> And what would be the best approach to integrating Git with these
> >> efforts? Just how often does one commit one's code to the version
> >> control system? Or do I have some GCEs (Gross Conceptual Errors) here?
> >> Can Git be set up to automatically keep track of my code as I create
> >> and edit it?
>
> >No, that's not how revision control works. You really don't want every
> >time you hit save to count as a new revision. That would be ugly.
>
> >Joel Spolsky has a good introduction to Mercurial (hg). Git is slightly
> >different, but the fundamentals are more or less equivalent:
>
> >http://hginit.com/
> ?
> >You can also watch Git For Ages 4 And Up:
>
> >http://www.youtube.com/watch?v=1ffBJ4sVUb4
>
>
> >The executive summary of how I use version control:
>
> >- work on bite-sized chunks of functionality
> >- when the tests all pass, commit the work done
> >- push changes to the master repo at least once per day
>
>
> >The way I use version control on my own is that I have typically use a
> >single branch. I rarely have to worry about contributions from others,
> >so it's just my changes. Make sure that all the relevent files (source
> >code, documentation, tests, images, etc.) are being tracked. Static
> >files which never change, like reference materials, should not be.
>
> >Starting from a point where all the tests pass, I decide to work on a
> >new feature, or fix a bug. A feature might be something as small as "fix
> >the documentation for this function", but *not* as big as "control
> >remote controlled space ship" -- in other words, a bite-sized chunk of
> >work, not a full meal. I write some tests, and write the minimal amount
> >of code code that makes those tests pass:
>
> >- write tests
> >- save tests
> >- write code
> >- save code
> >- run tests
> >- fix bugs in tests
> >- save tests
> >- write some more code
> >- save code
> >- run tests again
> >- write some more code
> >- save code
> >- run tests again
>
>
> >etc. Once the tests pass, then I have a feature and/or bug fix, and I
> >commit all the relevent changes to the VCS. hg automatically tracks
> >files, git requires you to remind it every single time what files are
> >being used, but either way, by the time I run `hg commit` or `git
> >commit` I have a complete, and hopefully working, bite-sized chunk of
> >code that has an obvious commit message:
>
> >"fix bug in spam function"
> >"correct spelling errors in module docs"
> >"rename function ham to spam"
> >"change function eggs from using a list to a dict"
> >"move class K into its own submodule"
>
> >etc. Notice that each change is small enough to encapsulate in a short
> >description, but big enough that some of them may require multiple
> >rounds of back-and-forth code-and-test before it works.
>
> >I run the tests even after seemingly innoculous changes to comments or
> >docstrings, especially docstrings. Edits to a docstring may break your
> >doctests, or even your code, if you accidentally break the quoting.
>
> >Then, when I am feeling satisfied that I've done a sufficiently large
> >amount of work, I then push those changes to the master repo (if any).
> >This allows me to work from various computers and still share the same
> >code base. "Sufficiently large" may mean a single change, or a full
> >day's work, or a whole lot of related changes that add up to one big
> >change, whatever you prefer. But it shouldn't be less than once per day.
>
> [...]
>
> >> And I would like to have all of that under version control, too. But
> >> while I am allowed to write my own programs for this CSA, I am not
> >> allowed to install anything else, strange as this may sound! Since the
> >> only functional editors in these bare-bones Solaris 10 environments
> >> are some simplistic default editor that I do not know the name of and
> >> vi, I long ago gravitated to doing my actual coding on my Windows PC
> >> (Being careful to save things with Unix line endings.) and FTPing to
> >> the environments where these programs will actually run. I AM allowed
> >> to install anything I want (within reason)on my PC. So I am thinking
> >> install and use Git there?
>
> >Yes.
> ----------------------------------------------------------------------
> On Fri, Apr 24, 2015 at 7:46 PM, Alan Gauld wrote:
> >On 24/04/15 23:52, boB Stepp wrote:
>
> >> There is just lil ol' me. I will have to research SCCS.
>
>
> >SCCS is great for a single, small team. It's marginally more complex
> >than more modern tools and it only works sensibly with text files
> >(binaries are just uuencoded which is pretty pointless!).
>
> >Basic usage is very simple:
> >1) create an SCCS directory in your project space - or you wind up
> >   with version files all over the place!
> >2) use the admin -i command to tell sccs to manage a file
> >3) use get to get a read only copy or get -e to get an editable one.
> >   (use -r to get a specific version)
> >4) use delta to save changes (it prompts you for change comments etc)
>
> >There are a bunch of other reporting and searching and admin
> >commands, but the above is all you need 90% of the time.
> >More modern versioning systems are better but SCCS should already
> >be installed on Solaris 10 if you have the development tools
> >installed, which I'm guessing you do or pretty much
> >nothing code-wise would work.
> ----------------------------------------------------------------------
> On Fri, Apr 24, 2015 at 8:24 PM, boB Stepp wrote:
> >On Fri, Apr 24, 2015 at 3:00 PM, Laura Creighton <lac at openend.se> wrote:
> >> In a message of Fri, 24 Apr 2015 14:09:45 -0500, boB Stepp writes:
>
> [...]
>
> >>>And I would like to have all of that under version control, too. But
> >>>while I am allowed to write my own programs for this CSA, I am not
> >>>allowed to install anything else, strange as this may sound! Since the
> >>>only functional editors in these bare-bones Solaris 10 environments
> >>>are some simplistic default editor that I do not know the name of and
> >>>vi, I long ago gravitated to doing my actual coding on my Windows PC
> >>>(Being careful to save things with Unix line endings.) and FTPing to
> >>>the environments where these programs will actually run. I AM allowed
> >>>to install anything I want (within reason)on my PC. So I am thinking
> >>>install and use Git there?
> >>
> >> Are you absolutely certain that you cannot install git on your
> bare-bones
> >> Solaris 10 environments?  Or plug in a memory stick and run code from
> >> there?  Because it would make your life so much easier ...
>
> >I think that I can get an exception here (See a post in response that
> >I made earlier today.). What I am *certain* of, is that I cannot
> >install anything on our clinical planning environment. The Solaris
> >workstation that I now have all to myself--I'm thinking they will now
> >let me do what I want with it. But I must double check... But anything
> >I develop there *should* work in the clinical environment. The
> >planning software is the same though that may change soon as there are
> >plans to go up a version and they may not want to do that on my
> >testing/development machine.
> ----------------------------------------------------------------------
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> https://mail.python.org/mailman/listinfo/tutor
>
>
> ------------------------------
>
> End of Tutor Digest, Vol 134, Issue 86
> **************************************
>



-- 
Cheers,

   Jon S. Engle
   jon.engle at gmail.com

From steve at pearwood.info  Sun Apr 26 01:07:31 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Apr 2015 09:07:31 +1000
Subject: [Tutor] Python Whois [was Re:  Tutor Digest, Vol 134, Issue 86]
In-Reply-To: <CAOpmNVEoS06FaTHnZSx2KwZiMku41rmXQVb82D3r9nvceGXGGw@mail.gmail.com>
References: <mailman.399.1429975810.3679.tutor@python.org>
 <CAOpmNVEoS06FaTHnZSx2KwZiMku41rmXQVb82D3r9nvceGXGGw@mail.gmail.com>
Message-ID: <20150425230730.GH5663@ando.pearwood.info>

Hi Jon,

Before I answer your question, first some mailing list housekeeping. If 
you are going to read and respond to messages here, please change from 
"Daily Digest" to individual messages. Your reply includes 500 
lines (about 10 or 12 pages!) of old messages. We've already seen those 
messages before, we don't need to see them again. And most of them have 
nothing to do with your question.

This is what happens when you reply to Digests. It is annoying to the 
reader, and for those people who pay for internet access by the byte 
(yes, there are still some of them) it costs them money. So please don't 
do it in the future.


Now, back to your question:


On Sat, Apr 25, 2015 at 02:13:50PM -0400, Juanald Reagan wrote:

> Okay, so it doesn't look like that worked...here is the traceback. I don't
> understand the second part of your request.
> 
> Jons-desktop:whois-0.7 2 jon$ python pythonwhois.py
> 
> 8.8.8.8
> 
> Traceback (most recent call last):
> 
>   File "pythonwhois.py", line 14, in <module>
> 
>     print results.asn_registry
> 
> AttributeError: 'dict' object has no attribute 'asn_registry'

Try these three lines instead:

     print type(results)
     print results
     print results['asn_registry']


The first two lines are to find out what sort of object the IPWhois 
result is, and hopefully what its contents are. I *think* it will be a 
dict, in which case the last line may be the answer you are looking for: 
to extract the 'asn_registry' field from the dict, you will use

    results['asn_registry']

Assuming that works, does it answer your question? If not, can you 
explain what you want to do?



-- 
Steve

From alan.gauld at btinternet.com  Sun Apr 26 01:25:59 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 26 Apr 2015 00:25:59 +0100
Subject: [Tutor] whois github package
In-Reply-To: <CAOpmNVHO=6GU2doxq2c8kcKyb8qQ9jcPMUZT9_VU+7x8V9TTsQ@mail.gmail.com>
References: <CAOpmNVHO=6GU2doxq2c8kcKyb8qQ9jcPMUZT9_VU+7x8V9TTsQ@mail.gmail.com>
Message-ID: <mhh7q4$9r8$1@ger.gmane.org>

On 25/04/15 14:46, Juanald Reagan wrote:
> Hello! I have a question regarding how to use/implement a package found at
> github.
>
> https://github.com/secynic/ipwhois


We are not experts on this here since this list s for people learning 
the core Python lamguage and its standard library. Howe er I see Steven 
has had a go at helping you.

Another thing you could try is using Pythons built in help() function:

After
>>> from ipwhois import IPWhois

Try
 >>> help(IPWhois)

>      obj = IPWhois(ipaddy)

Now try

 >>> help(obj)
 >>> help(obj.lookup)

That might give some clues about what methods exist and what they 
return. (Assuming the author included doc strings of course!

>      results = [obj.lookup()]
>      print results [0]
>
> This returns ALL the fields not just the "asn_registry" field.

That's what I'd expect since you put the output of lookup()
as the first element of the list. You then printed that element.

But if you showed us even a snippet of what that actually
looked like it would help us answer your question about
how to access it. Remember we don't know this package so
you have to show us what is happening not just summarize
what you think its doing.

 > I looked for documentation on github

Python documentation is often embedded in the module/objects
help() will often reveal it.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From dyoo at hashcollision.org  Sun Apr 26 01:38:15 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 25 Apr 2015 16:38:15 -0700
Subject: [Tutor] Looking up a value in a dictionary
Message-ID: <CAGZAPF4VBGQRSvvKFrtpayLxh8pcM85zYdLDwSreuDAzPXD5-g@mail.gmail.com>

On Sat, Apr 25, 2015 at 11:13 AM, Juanald Reagan <jon.engle at gmail.com> wrote:
> Okay, so it doesn't look like that worked...here is the traceback. I don't
> understand the second part of your request.
>
> Jons-desktop:whois-0.7 2 jon$ python pythonwhois.py
>
> 8.8.8.8
>
> Traceback (most recent call last):
>
>   File "pythonwhois.py", line 14, in <module>
>
>     print results.asn_registry
>
> AttributeError: 'dict' object has no attribute 'asn_registry'


Because of the lack of subject-line context, I'm having a hard time
following this thread.  I've changed the subject to "Looking up
attributes in a dictionary."  Trying to trace the context by looking
through the archive... ok, I see:

    https://mail.python.org/pipermail/tutor/2015-April/105122.html
    https://mail.python.org/pipermail/tutor/2015-April/105123.html

... got it....


Ok, so you're replying back to Stephen, about the code snippet he
proposed, and you're running into an error.  I think I understand
better now.


Please try changing:

    print results.asn_registry

to the two statements:

    print results.keys()
    print results['asn_registry']


The first statement shows what keys are in the results dictionary.
The second statement tries to print the value associated with
'asn_registry'.

The reason that the original suggestion didn't work here is because,
in Python, object attribute lookup is different from dictionary
lookup.  We guessed that 'results' was an object, and that you wanted
to look up the 'asn_registry' attribute of that object.

But from the error message, we see that 'results' is a dictionary.
Easy to correct.  You want to use a dictionary lookup instead.

The first print statement is there just to validate that there is such
a key 'asn_registry' within the 'results'.  It's possible that the key
is different, so the first print is there just as a double-check for
us.

From cybervigilante at gmail.com  Sun Apr 26 01:38:33 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sat, 25 Apr 2015 16:38:33 -0700
Subject: [Tutor] REPL format
Message-ID: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>

I'm curious why, when I read and decode a binary file from the net in one
fell swoop, the REPL prints it between parentheses, line by line but with
no commas, like a defective tuple. I can see breaking lines visually, at
\n, but if the parentheses don't mean anything I can't see including them.
Or do they mean something I've missed? Also, it's interesting that although
HTML is case-free, you have to get the case right for the java server page.
getbusesforroute.jsp doesn't work.

?import urllib.request
u = urllib.request.urlopen('
http://ctabustracker.com/bustime/map/getBusesForRoute.jsp?route=22')
data = u.read()
f = open('rt22.xml', 'wb')
f.write(data)
f.close()

f = open('rt22.xml', 'rb')
transit_info = str(f.read(), encoding='utf-8')

>>> transit_info
('<?xml version="1.0"?>\r\n'
 '\r\n'
 '\r\n'
 ... bunch of stuff ...
 '\t\t\t<wid2>222</wid2>            \t\r\n'
 '\t\t</bus>\r\n'
 '\r\n'
 '\r\n'
 '\r\n'
 '\t</buses>\r\n')



-- 
Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From dyoo at hashcollision.org  Sun Apr 26 02:38:58 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 25 Apr 2015 17:38:58 -0700
Subject: [Tutor] REPL format
In-Reply-To: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
References: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
Message-ID: <CAGZAPF4PpHP6cGCnm3UwhbjdB8u75kba5BoyYTe1hWcxk8aAGg@mail.gmail.com>

On Sat, Apr 25, 2015 at 4:38 PM, Jim Mooney <cybervigilante at gmail.com> wrote:
> I'm curious why, when I read and decode a binary file from the net in one
> fell swoop, the REPL prints it between parentheses, line by line but with
> no commas, like a defective tuple.


The REPL is trying to be nice here.  What you're seeing is a
representation that's using a little-known Python syntactic feature:
string literals can be spread across lines.  See:

    https://docs.python.org/2/reference/lexical_analysis.html#string-literal-concatenation

At the program's parse time, the Python compiler will join adjacent
string literals automatically.


It's a cute-but-nasty trick that some other languages do, such as C++.


I would strongly discourage not using it yourself in your own
programs: it's the source of a very common mistake.  Here's an
example:

####################
def f(x, y):
    print(x)
    print(y)

f("hello"
  "world")
####################

What do you expect to see?  What do you see?

So that's why I don't like this feature: makes it really hard to catch
mistakes when one is passing string literals as arguments and forgets
the comma.  Especially nasty when the function being called uses
optional arguments.


But I'm surprised, frankly, that you're seeing the standard Python
REPL using string literal concatenation, as in my memory, it was a lot
less accommodating.  Is this Python 3?

From dyoo at hashcollision.org  Sun Apr 26 02:42:15 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 25 Apr 2015 17:42:15 -0700
Subject: [Tutor] REPL format
In-Reply-To: <CAGZAPF4PpHP6cGCnm3UwhbjdB8u75kba5BoyYTe1hWcxk8aAGg@mail.gmail.com>
References: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
 <CAGZAPF4PpHP6cGCnm3UwhbjdB8u75kba5BoyYTe1hWcxk8aAGg@mail.gmail.com>
Message-ID: <CAGZAPF5qHN3yeQuDFa74HD0cYO8S7fK64Wz=D31bX2=FWeESEw@mail.gmail.com>

> I would strongly discourage not using it yourself in your own
> programs.

Ugh.  There was one too many negations there.  I deserved to make that
mistake, since my sentence structure was unnecessarily nested.  :P

I meant to say: "I would strongly discourage using literal string
concatenation in your own programs: it's the source of a very common
mistake..."

From alan.gauld at btinternet.com  Sun Apr 26 02:43:23 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 26 Apr 2015 01:43:23 +0100
Subject: [Tutor] REPL format
In-Reply-To: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
References: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
Message-ID: <mhhcb8$7vr$1@ger.gmane.org>

On 26/04/15 00:38, Jim Mooney wrote:

> ...it's interesting that although
> HTML is case-free, you have to get the case right for the java server page.
> getbusesforroute.jsp doesn't work.

That's because its a file name and has nothing to do with HTML.
The HTML is what's inside the file.

> ?import urllib.request
> u = urllib.request.urlopen('
> http://ctabustracker.com/bustime/map/getBusesForRoute.jsp?route=22')
> data = u.read()

What do you get if you print data here?
That will tell you whether its something to do with that you
get from the server or whether its to do with what you are
doing to the data when you save/read it.

> f = open('rt22.xml', 'wb')
> f.write(data)
> f.close()
>
> f = open('rt22.xml', 'rb')
> transit_info = str(f.read(), encoding='utf-8')
>
>>>> transit_info
> ('<?xml version="1.0"?>\r\n'
>   '\r\n'
>   '\r\n'
>   ... bunch of stuff ...
>   '\t\t\t<wid2>222</wid2>            \t\r\n'
>   '\t\t</bus>\r\n'

I can't reproduce this format in the interpreter so I don't
know what's going on. I seem to recall you are using Python 3,
is that correct?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From ben+python at benfinney.id.au  Sun Apr 26 03:03:22 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Sun, 26 Apr 2015 11:03:22 +1000
Subject: [Tutor] =?utf-8?q?Please_disable_=E2=80=9Cdigest_mode=E2=80=9D_be?=
 =?utf-8?q?fore_participating_=28was=3A_Tutor_Digest=2C_Vol_134=2C_Issue_8?=
 =?utf-8?q?6=29?=
References: <mailman.399.1429975810.3679.tutor@python.org>
 <CAOpmNVEoS06FaTHnZSx2KwZiMku41rmXQVb82D3r9nvceGXGGw@mail.gmail.com>
Message-ID: <85lhhfk8f9.fsf_-_@benfinney.id.au>

Juanald Reagan <jon.engle at gmail.com> writes:

> Okay, so it doesn't look like that worked...here is the traceback. I don't
> understand the second part of your request.

Juanold, to keep the context and thread of the discussion, please
respond to individual messages, not digests.

To do that, you first need to disable ?digest mode? on your
subscription. Change your settings by logging in here
<URL:https://mail.python.org/mailman/listinfo/python-list>.

Digest mode should only ever be used if you know for certain you will
never be responding to any message.

-- 
 \          ?I moved into an all-electric house. I forgot and left the |
  `\   porch light on all day. When I got home the front door wouldn't |
_o__)                                            open.? ?Steven Wright |
Ben Finney


From robertvstepp at gmail.com  Sun Apr 26 04:55:12 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 25 Apr 2015 21:55:12 -0500
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <CANDiX9KFMNsb8dL56OzxShS_JKny4we1RQKmVg2Jf+BJwpqL0A@mail.gmail.com>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
 <201504242000.t3OK0OoB001036@fido.openend.se>
 <robertvstepp@gmail.com>
 <CANDiX9LY7nF7g0iezmmHmoptgMgDrFKxic=pbt8qgUntYTsXbg@mail.gmail.com>
 <201504250820.t3P8KplL021923@fido.openend.se>
 <CANDiX9KFMNsb8dL56OzxShS_JKny4we1RQKmVg2Jf+BJwpqL0A@mail.gmail.com>
Message-ID: <CANDiX9JwRwWu7byCq5r7TRv9M7sDJdT32-kft6kOo+tJMUv0Jg@mail.gmail.com>

On Sat, Apr 25, 2015 at 10:58 AM, boB Stepp <robertvstepp at gmail.com> wrote:
> On Sat, Apr 25, 2015 at 3:20 AM, Laura Creighton <lac at openend.se> wrote:
>> In a message of Fri, 24 Apr 2015 20:24:38 -0500, boB Stepp writes:


>>>I think that I can get an exception here (See a post in response that
>>>I made earlier today.). What I am *certain* of, is that I cannot
>>>install anything on our clinical planning environment. The Solaris
>>>workstation that I now have all to myself--I'm thinking they will now
>>>let me do what I want with it. But I must double check... But anything
>>>I develop there *should* work in the clinical environment. The
>>>planning software is the same though that may change soon as there are
>>>plans to go up a version and they may not want to do that on my
>>>testing/development machine.
>>
>> This thought 'if it works here, it ought to work there' is an unworthy
>> thought for somebody who has learned to test their code. ;)  You go to your
>> new machine.  You pull down your tests and your code.  You run all your
>> tests.  When they pass, you don't just _think_ that the code _ought to_
>> run here -- you _know_ the code will run because it passes all its tests.
>
> You have a very gentle way of chastising me! ~(:>))

While driving around doing chores today, I realized that I have been
incredibly dense here! Of course I can carry my testing suites, etc.,
over to the production environment: This is will be all part of my
code base, which I AM allowed to implement. Duh! If all Python
standard libraries are installed on the two Python environments (2.4
and 2.6), then testing should not be an issue, other than taking the
time to backtrack and get it going.

Now VCS/DVCS programs is another matter entirely, but after hearing
Laura's and Alan's input, one or both these solutions can surely be
implemented. But is even this an issue? If I do my actual code writing
on my Windows PC on which I AM allowed to install Git or whatever, and
FTP the code to run to either the 810X or the production SE
environments, then I will always have version control in place. I
reread Steven's post tonight, and he actually answered affirmatively
to this question; it just did not penetrate until this evening.

boB

From robertvstepp at gmail.com  Sun Apr 26 05:09:44 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 25 Apr 2015 22:09:44 -0500
Subject: [Tutor] Introductory questions on test-driven development and
 implementing Git version control.
In-Reply-To: <20150425003654.GB5663@ando.pearwood.info>
References: <CANDiX9L-0pYmQeU2yGTUjGo124Ora5+YKxS2Kvt+7X9oNbO6nw@mail.gmail.com>
 <20150425003654.GB5663@ando.pearwood.info>
Message-ID: <CANDiX9Jv9JJdxskLHbSgmFyEz9a0wnB7wKgJ730s5vvxwx6gDw@mail.gmail.com>

On Fri, Apr 24, 2015 at 7:36 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> So many questions... let's hope I don't miss any... :-)
>
> On Fri, Apr 24, 2015 at 02:09:45PM -0500, boB Stepp wrote:
>
>> First question: What testing modules/frameworks should I start out
>> with? Doing a quick scan of the books I have, mention is made of
>> doctest and unittest modules in the Python standard libraries. But
>> mention is also made of two third party modules, nose and pytest.
>

[...]

> unittest is quite easy to use, and powerful. Some people complain that
> it is not very Pythonic, but I've never felt that. It is also based on a
> standard and much-copied Java library, so there are versions of unittest
> for many different languages. I quite like it.

I will definitely start out my learning by going this route. Will work
at work (Though Monday I must do an actual import of unittest to
ensure it is actually on both environments. Ya never know...) and also
at home.


>> And as to automated testing: I really, ..., really would like to
>> implement it on my side projects at work. But all such programs start
>> in a proprietary scripting environment, which can call external Python
>> (or other languages) scripts. The resulting final program is almost
>> always an unavoidable amount of propriety scripting language (Which I
>> always strive to minimize the amount of.), Solaris shell
>> commands/scripts and Python. As I have been learning more Python and
>> implementing it at work, I have found that the most successful
>> approach seems to be to first get all of the information I need out of
>> the CSA (commercial software environment) upfront, save it in temp
>> files, then call a Python script to start the heavy duty processing,
>> do everything possible in Python, generate a "reload" script file that
>> contains language the CSA understands, and finally run that inside the
>> CSA. How do I go about automating the testing of something like this?
>> And apply TDD write tests first principles?
>
> TDD principles apply to any programming language. So long as the
> language that you use to write the tests has ways of calling your shell
> scripts and CSA code, and seeing what results they get, you can test
> them.

CSA scripting can indeed call both its own scripts and external (to
the CSA) ones. But everything must start within the CSA, or none of
the CSA's scripts that are part of the overall program can be called.
As far as I know, there is no way to initiate a CSA script from the
outside, though just to double check I might post that question on the
CSA's Google group.

> However, I *religiously* write the documentation first. If I don't
> document what the function does, how will I know what the code should
> do or when I am finished?

Every day I code this sinks more deeply into my bones...

-- 
boB

From robertvstepp at gmail.com  Sun Apr 26 05:16:18 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 25 Apr 2015 22:16:18 -0500
Subject: [Tutor] Questions (and initial responses) on using version
 control [Was: Introductory questions on test-driven development and
 implementing Git version control.]
In-Reply-To: <CANDiX9JCMPoWNZFaFJO+_amZU+KKdMcxa9+imrwYjp=4diYR0A@mail.gmail.com>
References: <CANDiX9JCMPoWNZFaFJO+_amZU+KKdMcxa9+imrwYjp=4diYR0A@mail.gmail.com>
Message-ID: <CANDiX9K6AYG2poW89jMaF4BL+-Pi=8GBdPbw=q5p0shCeygjuw@mail.gmail.com>

On Sat, Apr 25, 2015 at 10:30 AM, boB Stepp <robertvstepp at gmail.com> wrote:
> On Fri, Apr 24, 2015 at 7:36 PM, Steven D'Aprano wrote:
>>On Fri, Apr 24, 2015 at 02:09:45PM -0500, boB Stepp wrote:
>
> [...]
>
>>> And what would be the best approach to integrating Git with these
>>> efforts? Just how often does one commit one's code to the version
>>> control system? Or do I have some GCEs (Gross Conceptual Errors) here?
>>> Can Git be set up to automatically keep track of my code as I create
>>> and edit it?

[...]

>>The executive summary of how I use version control:
>
>>- work on bite-sized chunks of functionality
>>- when the tests all pass, commit the work done
>>- push changes to the master repo at least once per day
>
>
>>The way I use version control on my own is that I have typically use a
>>single branch. I rarely have to worry about contributions from others,
>>so it's just my changes. Make sure that all the relevent files (source
>>code, documentation, tests, images, etc.) are being tracked. Static
>>files which never change, like reference materials, should not be.
>
>>Starting from a point where all the tests pass, I decide to work on a
>>new feature, or fix a bug. A feature might be something as small as "fix
>>the documentation for this function", but *not* as big as "control
>>remote controlled space ship" -- in other words, a bite-sized chunk of
>>work, not a full meal. I write some tests, and write the minimal amount
>>of code code that makes those tests pass:
>
>>- write tests
>>- save tests
>>- write code
>>- save code
>>- run tests
>>- fix bugs in tests
>>- save tests
>>- write some more code
>>- save code
>>- run tests again
>>- write some more code
>>- save code
>>- run tests again
>
>
>>etc. Once the tests pass, then I have a feature and/or bug fix, and I
>>commit all the relevent changes to the VCS. hg automatically tracks
>>files, git requires you to remind it every single time what files are
>>being used, but either way, by the time I run `hg commit` or `git
>>commit` I have a complete, and hopefully working, bite-sized chunk of
>>code that has an obvious commit message:
>
>>"fix bug in spam function"
>>"correct spelling errors in module docs"
>>"rename function ham to spam"
>>"change function eggs from using a list to a dict"
>>"move class K into its own submodule"
>
>>etc. Notice that each change is small enough to encapsulate in a short
>>description, but big enough that some of them may require multiple
>>rounds of back-and-forth code-and-test before it works.
>
>>I run the tests even after seemingly innoculous changes to comments or
>>docstrings, especially docstrings. Edits to a docstring may break your
>>doctests, or even your code, if you accidentally break the quoting.
>
>>Then, when I am feeling satisfied that I've done a sufficiently large
>>amount of work, I then push those changes to the master repo (if any).
>>This allows me to work from various computers and still share the same
>>code base. "Sufficiently large" may mean a single change, or a full
>>day's work, or a whole lot of related changes that add up to one big
>>change, whatever you prefer. But it shouldn't be less than once per day.

Thanks for taking the time to share your workflow. It is very helpful for me.

> [...]
>
>>> And I would like to have all of that under version control, too. But
>>> while I am allowed to write my own programs for this CSA, I am not
>>> allowed to install anything else, strange as this may sound! Since the
>>> only functional editors in these bare-bones Solaris 10 environments
>>> are some simplistic default editor that I do not know the name of and
>>> vi, I long ago gravitated to doing my actual coding on my Windows PC
>>> (Being careful to save things with Unix line endings.) and FTPing to
>>> the environments where these programs will actually run. I AM allowed
>>> to install anything I want (within reason)on my PC. So I am thinking
>>> install and use Git there?
>
>>Yes.

This is what I plan to do. I have started reading the free online
book, "Pro Git--Everything You Need to Know About Git, 2nd ed., c2014,
which is accessible via the Git website. I also watched the video
about Git for 4-year olds. Long video, but it gave a good overview of
the Git way of implementing things. Again, thanks!

I think that after reading the first two chapters of the book, I will
know more than enough to get started. In actuality, after watching the
video last night, I could probably get going now. But I am an
inveterate book reader...

boB

From steve at pearwood.info  Sun Apr 26 06:28:04 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Apr 2015 14:28:04 +1000
Subject: [Tutor] REPL format
In-Reply-To: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
References: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
Message-ID: <20150426042804.GI5663@ando.pearwood.info>

On Sat, Apr 25, 2015 at 04:38:33PM -0700, Jim Mooney wrote:
> I'm curious why, when I read and decode a binary file from the net in one
> fell swoop, the REPL prints it between parentheses, line by line but with
> no commas, like a defective tuple.

What REPL are you using? I can't reproduce what you are 
reporting in the standard Python 3.3 interactive interpreter. When I 
print the transit_info I get a single block of text:


'<?xml version="1.0"?>\r\n\r\n ... </buses>\r\n'

which my terminal then wraps over multiple lines.


> I can see breaking lines visually, at
> \n, but if the parentheses don't mean anything I can't see including them.
> Or do they mean something I've missed? Also, it's interesting that although
> HTML is case-free, you have to get the case right for the java server page.
> getbusesforroute.jsp doesn't work.

That has nothing to do with HTML.

HTML is a file format, and it is case-insensitive. <b> and <B> are the 
same tag. But the http protocol has nothing to do with the contents of 
the files. When you give a URL like:

http://ctabustracker.com/bustime/map/getBusesForRoute.jsp?route=22

parts of it are case-insensitive and parts may not be.

The domain part:

    ctabustracker.com

is handled by the DNS system, and is case-insensitive. You could write 
http://cTaBuStRaCkEr.CoM/ if you like, and it would give you the same 
result.

But the part after the domain is controlled by the web server for that 
domain, and that depends on the web server. Some web servers may choose 
to be case-insensitive. Others may be case-sensitive. The local part of 
the URL that follows the domain is under control of the web server, 
which could do anything it likes.


-- 
Steve

From steve at pearwood.info  Sun Apr 26 10:38:39 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Apr 2015 18:38:39 +1000
Subject: [Tutor] REPL format
In-Reply-To: <CAGZAPF4PpHP6cGCnm3UwhbjdB8u75kba5BoyYTe1hWcxk8aAGg@mail.gmail.com>
References: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
 <CAGZAPF4PpHP6cGCnm3UwhbjdB8u75kba5BoyYTe1hWcxk8aAGg@mail.gmail.com>
Message-ID: <20150426083838.GJ5663@ando.pearwood.info>

On Sat, Apr 25, 2015 at 05:38:58PM -0700, Danny Yoo wrote:
> On Sat, Apr 25, 2015 at 4:38 PM, Jim Mooney <cybervigilante at gmail.com> wrote:
> > I'm curious why, when I read and decode a binary file from the net in one
> > fell swoop, the REPL prints it between parentheses, line by line but with
> > no commas, like a defective tuple.
> 
> 
> The REPL is trying to be nice here.  What you're seeing is a
> representation that's using a little-known Python syntactic feature:
> string literals can be spread across lines.  See:
> 
>     https://docs.python.org/2/reference/lexical_analysis.html#string-literal-concatenation
> 
> At the program's parse time, the Python compiler will join adjacent
> string literals automatically.

It's not specifically across lines. Any two adjacent string literals 
will be concatenated, even if they have different string delimiters:

    '"You can' "'t do that!" '" he said.'

is arguable somewhat nicer than either of these alternatives:

    '"You can\'t do that!" he said.'
    "\"You can't do that!\" he said."


(Well, to be completely honest, I don't that *any* of the solutions to 
the problem of using both sorts of quotation marks in the same string is 
nice, but its good to have options.)

Where automatic concatenation of string literals really comes into 
its own is when you have a long template string or error message, for 
example, which won't fit on a single line:

    message = "Doh, a deer, a female deer; Ray, a drop of golden sun; 
Me, a name I call myself; Far, a long long way to run; So, a needle 
pulling thread; La, a note to follow So; Tea, a drink with jam and 
bread."


We could use a triple quoted string:

    message = """Doh, a deer, a female deer;
                 Ray, a drop of golden sun;
                 Me, a name I call myself;
                 Far, a long long way to run;
                 So, a needle pulling thread;
                 La, a note to follow So;
                 Tea, a drink with jam and bread."""

But that not only includes line breaks, but the second line onwards is 
indented. We can break it up into substrings, and using a surrounding 
pair of round brackets to continue the expression over multiple lines, 
we can then use explicit concatenation:

    message = ("Doh, a deer, a female deer;" +
               " Ray, a drop of golden sun;" + 
               " Me, a name I call myself;" +
               " Far, a long long way to run;" +
               " So, a needle pulling thread;" +
               " La, a note to follow So;" +
               " Tea, a drink with jam and bread."
               )

but that has the disadvantage that the concatenation may be performed at 
runtime. (In fact, recent versions of CPython will do that at compile 
time, but it is not guaranteed by the language. Past versions did not; 
future versions may not, and other implementations like PyPy, 
IronPython, Jython and others may not either.)

To my mind, the least unpleasant version is this one, using implicit 
concatenation:

    message = (
        "Doh, a deer, a female deer; Ray, a drop of golden sun;"
        " Me, a name I call myself; Far, a long long way to run;"
        " So, a needle pulling thread; La, a note to follow So;"
        " Tea, a drink with jam and bread."
        )


> It's a cute-but-nasty trick that some other languages do, such as C++.
> 
> 
> I would strongly discourage not using it yourself in your own
> programs: it's the source of a very common mistake.  Here's an
> example:

I agree that this is a feature which can be abused and misused, but I 
disagree with Danny about avoiding it. I think that it works very well 
in the above example.

 
> So that's why I don't like this feature: makes it really hard to catch
> mistakes when one is passing string literals as arguments and forgets
> the comma.  Especially nasty when the function being called uses
> optional arguments.

I acknowledge that this scenario can and does happen in real life, but I 
don't think it is common. It only occurs when you have two consecutive 
arguments which are both string literals, and you forget the comma 
between them. How often does that happen? It cannot occur if one or more 
of the arguments are variables:

    greeting = "Hello "
    function(greeting "world!")  # Syntax error.




-- 
Steve

From cybervigilante at gmail.com  Sun Apr 26 03:28:46 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sat, 25 Apr 2015 18:28:46 -0700
Subject: [Tutor] REPL format
In-Reply-To: <mhhcb8$7vr$1@ger.gmane.org>
References: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
 <mhhcb8$7vr$1@ger.gmane.org>
Message-ID: <CALRAYNX9FGOjOprReR+94xQegeWVHML4KDTMKUug3YkwT=ErhQ@mail.gmail.com>

On 25 April 2015 at 17:43, Alan Gauld <alan.gauld at btinternet.com> wrote:


> know what's going on. I seem to recall you are using Python 3,
> is that correct?
>
>
I guess I should specify from now on py3 on win xp

Another question - why does the first assignment work but not the second. I
can see it's a syntax error but if Py can unpack in the first case why
can't it unpack the same thing in the second?

>>> a, *b = 'good', 'bad', 'ugly'
>>> a
'good'
>>> b
['bad', 'ugly']
>>> a, *b = 'ham', 'eggs', 'spam'
>>> a
'ham'
>>> b
['eggs', 'spam']
>>> *b = 'eggs', 'spam'
SyntaxError: starred assignment target must be in a list or tuple
>>>

-- 
Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From cybervigilante at gmail.com  Sun Apr 26 03:45:55 2015
From: cybervigilante at gmail.com (Jim Mooney)
Date: Sat, 25 Apr 2015 18:45:55 -0700
Subject: [Tutor]
	=?utf-8?q?Please_disable_=E2=80=9Cdigest_mode=E2=80=9D_be?=
	=?utf-8?q?fore_participating_=28was=3A_Tutor_Digest=2C_Vol_134=2C_?=
	=?utf-8?q?Issue_86=29?=
In-Reply-To: <85lhhfk8f9.fsf_-_@benfinney.id.au>
References: <mailman.399.1429975810.3679.tutor@python.org>
 <CAOpmNVEoS06FaTHnZSx2KwZiMku41rmXQVb82D3r9nvceGXGGw@mail.gmail.com>
 <85lhhfk8f9.fsf_-_@benfinney.id.au>
Message-ID: <CALRAYNXyqtvLbAodE47T1ndNc9+mPHaky=s1dNVFtBL9y3qj2w@mail.gmail.com>

On 25 April 2015 at 18:03, Ben Finney <ben+python at benfinney.id.au> wrote:

> Digest mode should only ever be used if you know for certain you will
> never be responding to any message.
>

That brings up a great shortcut if you use gmail. If you select some text
before reply that's All that is sent. Cuts way down on huge reply chains,
and saves mooching through your reply to delete all the garbola. However,
it has to be enabled in google labs:
http://blog.jgc.org/2013/01/the-greatest-google-mail-feature-you.html

I just used it to quote only the three lines above (if I got it right ;')

It could be some other mail services have this, too.  You'd have to look.

-- 
Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From cybervigilante at gmail.com  Sun Apr 26 06:18:53 2015
From: cybervigilante at gmail.com (Jim Mooney Py3winXP)
Date: Sat, 25 Apr 2015 21:18:53 -0700
Subject: [Tutor] output is all integer when there should be some floats
Message-ID: <CALRAYNWgqDM=XNCs+gwSaAXUa9WpfAOPX7CAcBtBPWfhq-=Z1w@mail.gmail.com>

It seems odd to me that there are three tests to see if user input is
digits - isdecimal, isdigit, isnumeric, but nothing to test for a float
unless you use a try - except. Or did I miss something? Anyway, I tried a
try - except, but I don't see why my output is all integer when I only
convert to integer if it passes the is_integer test:

user_values = []
while True:
    user_input = input("Give me a number: ")
    if user_input.lower() == 'done': break
    try:
        user_input = float(user_input)
        if user_input.is_integer: user_input = int(user_input)
        user_values.append(user_input)
    except Exception as err:
        print("You entered {0}, which is not a valid number: error -
{1}".format(user_input, err))
        continue

print("Your entered numbers were {0}".format(user_values))  #only integers
print, even when I entered some floats

-- 
Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From cybervigilante at gmail.com  Sun Apr 26 07:03:29 2015
From: cybervigilante at gmail.com (Jim Mooney Py3winXP)
Date: Sat, 25 Apr 2015 22:03:29 -0700
Subject: [Tutor] REPL format
In-Reply-To: <20150426042804.GI5663@ando.pearwood.info>
References: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
 <20150426042804.GI5663@ando.pearwood.info>
Message-ID: <CALRAYNU=T1X07vMR938mPin8+1FMQ_3zw=GoTjuoANLtmqAnLQ@mail.gmail.com>

On 25 April 2015 at 21:28, Steven D'Aprano <steve at pearwood.info> wrote:

> What REPL are you using? I can't reproduce what you are
> reporting in the standard Python 3.3 interactive interpreter. When I
> print the transit_info I get a single block of text:
>

Ah, found the problem. I was looking at PyScripter output. When I ran it
from the console and immediately went into interpreter mode to look at the
transit_info, I got the block of text. I have to remember to go to the
console if I'm befuddled by output ;')  Although I really like PyScripter.
I tried the free PyCharm but it involves a lot of garbola and slows me down
at my level. Free Wing is missing a lot of conveniences, like commenting
out a whole block. All the other free editors had various problems. Just my
opinion.

A side note on using Py3, which I now have in my header so I don't have to
keep mentioning it - I decided to use it since most big modules are ported
but I just found out the all-important google api is py 2 only. Bummer. Odd
that google was the major mover in killing IE6 but isn't moving ahead on
Python. PayPal does Py3, though.

-- 
Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From jon.engle at gmail.com  Sun Apr 26 05:02:56 2015
From: jon.engle at gmail.com (Juanald Reagan)
Date: Sat, 25 Apr 2015 23:02:56 -0400
Subject: [Tutor] Tutor Digest, Vol 134, Issue 89
In-Reply-To: <mailman.478.1430009022.3679.tutor@python.org>
References: <mailman.478.1430009022.3679.tutor@python.org>
Message-ID: <CAOpmNVEePqfWjo9o2G1gW63jF+nixrg4WbWZM1+R8RVnC05_+A@mail.gmail.com>

Sorry for not providing all the relevant info, let me provide some
additional details:

When I run this code:

    from ipwhois import IPWhois
    file=open('ip.txt', 'r')
    ipaddy=file.read()
    obj = IPWhois(ipaddy)
    results = [obj.lookup()]
    print results [0]

I receive this output:

Jons-computer:whois-0.7 2 jon$ python pythonwhois.py

{'asn_registry': 'arin', 'asn_date': '', 'asn_country_code': 'US', 'raw':
None, 'asn_cidr': '8.8.8.0/24', 'raw_referral': None, 'query': '8.8.8.8',
'referral': None, 'nets': [{'updated': '2012-02-24T00:00:00', 'handle':
'NET-8-0-0-0-1', 'description': 'Level 3 Communications, Inc.',
'tech_emails': 'ipaddressing at level3.com', 'abuse_emails': 'abuse at level3.com',
'postal_code': '80021', 'address': '1025 Eldorado Blvd.', 'cidr': '8.0.0.0/8',
'city': 'Broomfield', 'name': 'LVLT-ORG-8-8', 'created':
'1992-12-01T00:00:00', 'country': 'US', 'state': 'CO', 'range': '8.0.0.0 -
8.255.255.255', 'misc_emails': None}, {'updated': '2014-03-14T00:00:00',
'handle': 'NET-8-8-8-0-1', 'description': 'Google Inc.', 'tech_emails': '
arin-contact at google.com', 'abuse_emails': 'arin-contact at google.com',
'postal_code': '94043', 'address': '1600 Amphitheatre Parkway', 'cidr': '
8.8.8.0/24', 'city': 'Mountain View', 'name': 'LVLT-GOGL-8-8-8', 'created':
'2014-03-14T00:00:00', 'country': 'US', 'state': 'CA', 'range': None,
'misc_emails': None}], 'asn': '15169'}

I would like to refine this information and only receive these fields as my
output:
{'asn_registry': 'arin',description': 'Google Inc.',}

I was hoping there was a way to take each one of these items and read them
into a list so I can pick and choose the fields I want by index. I believe
all fields are currently stored in index position 0.

Here are the helper file contents:

 |      Args:

 |          inc_raw: Boolean for whether to include the raw whois results in

 |              the returned dictionary.

 |          retry_count: The number of times to retry in case socket errors,

 |              timeouts, connection resets, etc. are encountered.

 |          get_referral: Boolean for whether to retrieve referral whois

 |              information, if available.

 |          extra_blacklist: A list of blacklisted whois servers in
addition to

 |              the global BLACKLIST.

 |          ignore_referral_errors: Boolean for whether to ignore and
continue

 |              when an exception is encountered on referral whois lookups.

 |

 |      Returns:

 |          Dictionary: A dictionary containing the following keys:

 |                  query (String) - The IP address.

 |                  asn (String) - The Autonomous System Number.

 |                  asn_date (String) - The ASN Allocation date.

 |                  asn_registry (String) - The assigned ASN registry.

 |                  asn_cidr (String) - The assigned ASN CIDR.

 |                  asn_country_code (String) - The assigned ASN country
code.

 |                  nets (List) - Dictionaries containing network
information

 |                      which consists of the fields listed in the NIC_WHOIS

 |                      dictionary. Certain IPs have more granular network

 |                      listings, hence the need for a list object.

 |                  raw (String) - Raw whois results if the inc_raw
parameter

 |                      is True.

 |                  referral (Dictionary) - Dictionary containing referral

 |                      whois information if get_referral is True and the

 |                      server isn't blacklisted. Consists of fields listed

 |                      in the RWHOIS dictionary. Additional referral server

 |                      informaion is added in the server and port keys.

 |                  raw_referral (String) - Raw referral whois results if
the

 |                      inc_raw parameter is True.

 |

 |  *lookup_rws*(self, inc_raw=False, retry_count=3)

 |      The function for retrieving and parsing whois information for an IP

 |      address via HTTP (Whois-RWS).

 |

 |      NOTE: This should be faster than IPWhois.lookup(), but may not be as

 |          reliable. AFRINIC does not have a Whois-RWS service yet. We have

 |          to rely on the Ripe RWS service, which does not contain all of
the

 |          data we need. LACNIC RWS is in beta v2.

 |

 |      Args:

 |          inc_raw: Boolean for whether to include the raw whois results in

 |              the returned dictionary.

 |          retry_count: The number of times to retry in case socket errors,

 |              timeouts, connection resets, etc. are encountered.

 |

 |      Returns:

 |          Dictionary: A dictionary containing the following keys:

 |                  query (String) - The IP address.

 |                  asn (String) - The Autonomous System Number.

 |                  asn_date (String) - The ASN Allocation date.

 |                  asn_registry (String) - The assigned ASN registry.

 |                  asn_cidr (String) - The assigned ASN CIDR.

 |                  asn_country_code (String) - The assigned ASN country
code.

 |                  nets (List) - Dictionaries containing network
information

 |                      which consists of the fields listed in the NIC_WHOIS

 |                      dictionary. Certain IPs have more granular network

 |                      listings, hence the need for a list object.

 |                  raw (Dictionary) - Whois results in Json format if the

 |                      inc_raw parameter is True.


On Sat, Apr 25, 2015 at 8:43 PM, <tutor-request at python.org> wrote:

> Send Tutor mailing list submissions to
>         tutor at python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://mail.python.org/mailman/listinfo/tutor
> or, via email, send a message with subject or body 'help' to
>         tutor-request at python.org
>
> You can reach the person managing the list at
>         tutor-owner at python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Tutor digest..."
>
>
> Today's Topics:
>
>    1. Re: whois github package (Alan Gauld)
>    2. Looking up a value in a dictionary (Danny Yoo)
>    3. REPL format (Jim Mooney)
>    4. Re: REPL format (Danny Yoo)
>    5. Re: REPL format (Danny Yoo)
>    6. Re: REPL format (Alan Gauld)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Sun, 26 Apr 2015 00:25:59 +0100
> From: Alan Gauld <alan.gauld at btinternet.com>
> To: tutor at python.org
> Subject: Re: [Tutor] whois github package
> Message-ID: <mhh7q4$9r8$1 at ger.gmane.org>
> Content-Type: text/plain; charset=windows-1252; format=flowed
>
> On 25/04/15 14:46, Juanald Reagan wrote:
> > Hello! I have a question regarding how to use/implement a package found
> at
> > github.
> >
> > https://github.com/secynic/ipwhois
>
>
> We are not experts on this here since this list s for people learning
> the core Python lamguage and its standard library. Howe er I see Steven
> has had a go at helping you.
>
> Another thing you could try is using Pythons built in help() function:
>
> After
> >>> from ipwhois import IPWhois
>
> Try
>  >>> help(IPWhois)
>
> >      obj = IPWhois(ipaddy)
>
> Now try
>
>  >>> help(obj)
>  >>> help(obj.lookup)
>
> That might give some clues about what methods exist and what they
> return. (Assuming the author included doc strings of course!
>
> >      results = [obj.lookup()]
> >      print results [0]
> >
> > This returns ALL the fields not just the "asn_registry" field.
>
> That's what I'd expect since you put the output of lookup()
> as the first element of the list. You then printed that element.
>
> But if you showed us even a snippet of what that actually
> looked like it would help us answer your question about
> how to access it. Remember we don't know this package so
> you have to show us what is happening not just summarize
> what you think its doing.
>
>  > I looked for documentation on github
>
> Python documentation is often embedded in the module/objects
> help() will often reveal it.
>
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
>
>
> ------------------------------
>
> Message: 2
> Date: Sat, 25 Apr 2015 16:38:15 -0700
> From: Danny Yoo <dyoo at hashcollision.org>
> To: Juanald Reagan <jon.engle at gmail.com>
> Cc: "tutor at python.org" <tutor at python.org>
> Subject: [Tutor] Looking up a value in a dictionary
> Message-ID:
>         <
> CAGZAPF4VBGQRSvvKFrtpayLxh8pcM85zYdLDwSreuDAzPXD5-g at mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> On Sat, Apr 25, 2015 at 11:13 AM, Juanald Reagan <jon.engle at gmail.com>
> wrote:
> > Okay, so it doesn't look like that worked...here is the traceback. I
> don't
> > understand the second part of your request.
> >
> > Jons-desktop:whois-0.7 2 jon$ python pythonwhois.py
> >
> > 8.8.8.8
> >
> > Traceback (most recent call last):
> >
> >   File "pythonwhois.py", line 14, in <module>
> >
> >     print results.asn_registry
> >
> > AttributeError: 'dict' object has no attribute 'asn_registry'
>
>
> Because of the lack of subject-line context, I'm having a hard time
> following this thread.  I've changed the subject to "Looking up
> attributes in a dictionary."  Trying to trace the context by looking
> through the archive... ok, I see:
>
>     https://mail.python.org/pipermail/tutor/2015-April/105122.html
>     https://mail.python.org/pipermail/tutor/2015-April/105123.html
>
> ... got it....
>
>
> Ok, so you're replying back to Stephen, about the code snippet he
> proposed, and you're running into an error.  I think I understand
> better now.
>
>
> Please try changing:
>
>     print results.asn_registry
>
> to the two statements:
>
>     print results.keys()
>     print results['asn_registry']
>
>
> The first statement shows what keys are in the results dictionary.
> The second statement tries to print the value associated with
> 'asn_registry'.
>
> The reason that the original suggestion didn't work here is because,
> in Python, object attribute lookup is different from dictionary
> lookup.  We guessed that 'results' was an object, and that you wanted
> to look up the 'asn_registry' attribute of that object.
>
> But from the error message, we see that 'results' is a dictionary.
> Easy to correct.  You want to use a dictionary lookup instead.
>
> The first print statement is there just to validate that there is such
> a key 'asn_registry' within the 'results'.  It's possible that the key
> is different, so the first print is there just as a double-check for
> us.
>
>
> ------------------------------
>
> Message: 3
> Date: Sat, 25 Apr 2015 16:38:33 -0700
> From: Jim Mooney <cybervigilante at gmail.com>
> To: "tutor at python.org" <tutor at python.org>
> Subject: [Tutor] REPL format
> Message-ID:
>         <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=
> Y9yJBwbWeSA at mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> I'm curious why, when I read and decode a binary file from the net in one
> fell swoop, the REPL prints it between parentheses, line by line but with
> no commas, like a defective tuple. I can see breaking lines visually, at
> \n, but if the parentheses don't mean anything I can't see including them.
> Or do they mean something I've missed? Also, it's interesting that although
> HTML is case-free, you have to get the case right for the java server page.
> getbusesforroute.jsp doesn't work.
>
> ?import urllib.request
> u = urllib.request.urlopen('
> http://ctabustracker.com/bustime/map/getBusesForRoute.jsp?route=22')
> data = u.read()
> f = open('rt22.xml', 'wb')
> f.write(data)
> f.close()
>
> f = open('rt22.xml', 'rb')
> transit_info = str(f.read(), encoding='utf-8')
>
> >>> transit_info
> ('<?xml version="1.0"?>\r\n'
>  '\r\n'
>  '\r\n'
>  ... bunch of stuff ...
>  '\t\t\t<wid2>222</wid2>            \t\r\n'
>  '\t\t</bus>\r\n'
>  '\r\n'
>  '\r\n'
>  '\r\n'
>  '\t</buses>\r\n')
>
>
>
> --
> Jim
>
> If you only had one hour left to live, would you spend it on Facebook,
> Twitter, or Google Plus?
>
>
> ------------------------------
>
> Message: 4
> Date: Sat, 25 Apr 2015 17:38:58 -0700
> From: Danny Yoo <dyoo at hashcollision.org>
> To: Jim Mooney <cybervigilante at gmail.com>
> Cc: "tutor at python.org" <tutor at python.org>
> Subject: Re: [Tutor] REPL format
> Message-ID:
>         <
> CAGZAPF4PpHP6cGCnm3UwhbjdB8u75kba5BoyYTe1hWcxk8aAGg at mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> On Sat, Apr 25, 2015 at 4:38 PM, Jim Mooney <cybervigilante at gmail.com>
> wrote:
> > I'm curious why, when I read and decode a binary file from the net in one
> > fell swoop, the REPL prints it between parentheses, line by line but with
> > no commas, like a defective tuple.
>
>
> The REPL is trying to be nice here.  What you're seeing is a
> representation that's using a little-known Python syntactic feature:
> string literals can be spread across lines.  See:
>
>
> https://docs.python.org/2/reference/lexical_analysis.html#string-literal-concatenation
>
> At the program's parse time, the Python compiler will join adjacent
> string literals automatically.
>
>
> It's a cute-but-nasty trick that some other languages do, such as C++.
>
>
> I would strongly discourage not using it yourself in your own
> programs: it's the source of a very common mistake.  Here's an
> example:
>
> ####################
> def f(x, y):
>     print(x)
>     print(y)
>
> f("hello"
>   "world")
> ####################
>
> What do you expect to see?  What do you see?
>
> So that's why I don't like this feature: makes it really hard to catch
> mistakes when one is passing string literals as arguments and forgets
> the comma.  Especially nasty when the function being called uses
> optional arguments.
>
>
> But I'm surprised, frankly, that you're seeing the standard Python
> REPL using string literal concatenation, as in my memory, it was a lot
> less accommodating.  Is this Python 3?
>
>
> ------------------------------
>
> Message: 5
> Date: Sat, 25 Apr 2015 17:42:15 -0700
> From: Danny Yoo <dyoo at hashcollision.org>
> To: Jim Mooney <cybervigilante at gmail.com>
> Cc: "tutor at python.org" <tutor at python.org>
> Subject: Re: [Tutor] REPL format
> Message-ID:
>         <CAGZAPF5qHN3yeQuDFa74HD0cYO8S7fK64Wz=D31bX2=
> FWeESEw at mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> > I would strongly discourage not using it yourself in your own
> > programs.
>
> Ugh.  There was one too many negations there.  I deserved to make that
> mistake, since my sentence structure was unnecessarily nested.  :P
>
> I meant to say: "I would strongly discourage using literal string
> concatenation in your own programs: it's the source of a very common
> mistake..."
>
>
> ------------------------------
>
> Message: 6
> Date: Sun, 26 Apr 2015 01:43:23 +0100
> From: Alan Gauld <alan.gauld at btinternet.com>
> To: tutor at python.org
> Subject: Re: [Tutor] REPL format
> Message-ID: <mhhcb8$7vr$1 at ger.gmane.org>
> Content-Type: text/plain; charset=windows-1252; format=flowed
>
> On 26/04/15 00:38, Jim Mooney wrote:
>
> > ...it's interesting that although
> > HTML is case-free, you have to get the case right for the java server
> page.
> > getbusesforroute.jsp doesn't work.
>
> That's because its a file name and has nothing to do with HTML.
> The HTML is what's inside the file.
>
> > ?import urllib.request
> > u = urllib.request.urlopen('
> > http://ctabustracker.com/bustime/map/getBusesForRoute.jsp?route=22')
> > data = u.read()
>
> What do you get if you print data here?
> That will tell you whether its something to do with that you
> get from the server or whether its to do with what you are
> doing to the data when you save/read it.
>
> > f = open('rt22.xml', 'wb')
> > f.write(data)
> > f.close()
> >
> > f = open('rt22.xml', 'rb')
> > transit_info = str(f.read(), encoding='utf-8')
> >
> >>>> transit_info
> > ('<?xml version="1.0"?>\r\n'
> >   '\r\n'
> >   '\r\n'
> >   ... bunch of stuff ...
> >   '\t\t\t<wid2>222</wid2>            \t\r\n'
> >   '\t\t</bus>\r\n'
>
> I can't reproduce this format in the interpreter so I don't
> know what's going on. I seem to recall you are using Python 3,
> is that correct?
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> https://mail.python.org/mailman/listinfo/tutor
>
>
> ------------------------------
>
> End of Tutor Digest, Vol 134, Issue 89
> **************************************
>



-- 
Cheers,

   Jon S. Engle
   jon.engle at gmail.com

From smarugg at gmail.com  Sun Apr 26 05:23:44 2015
From: smarugg at gmail.com (Spencer For Friends)
Date: Sat, 25 Apr 2015 23:23:44 -0400
Subject: [Tutor] Python tkinter. Opening another script from main window
 stop main window from functioning. Looking for Help
Message-ID: <CAAAQYPcHjgPjqLaqRO5jy0FA_Ag0fnL0vit=2Nuj1kLk3F6DwQ@mail.gmail.com>

Hi all. I'm new to Python and I'm trying my best to learn, but I'm really
struggling with some problems.

I'm using a tkinter window with a button on it to open another Python
script. When the button is clicked and the new script loads it opens up
it's own window over top of my tkinter window. The problem is, when I
switch back to my tkinter window, none of the buttons are click-able
anymore. The whole windows is unresponsive. The click animation on the
button doesn't even function. Any help to resolve this would be greatly
appreciated. Here is my code.


from Tkinter import *
from PIL import ImageTk, Image
import os
from magicassistantcsv import MagicAssistantCSV

CSV_FILE = "data/inventory.csv"
csv = MagicAssistantCSV(CSV_FILE, append=True)
root = Tk()

#Add POP Logo Image To Screen

POPimg = ImageTk.PhotoImage(Image.open("images/poplogo.png"))
panel = Label(root, image = POPimg)
panel.grid(row=0, column =0, sticky=W)

#Add Magic Logo Image

mtgimg = ImageTk.PhotoImage(Image.open("images/mtgcardbot.png"))
panel = Label(root, image = mtgimg)
panel.grid(row=1, column =0, sticky=W, padx=300, pady=180)


#Make Window Full Screen

w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (w, h))

#Add Execute Functionality To Button

def callback():
    execfile("test.py")

def endTrade():
    csv.close()


button1 = Button(text = 'Scan Your Card!', font=('Arial', '20'), fg =
'red', command = callback)
button2 = Button(text = 'Scan Complete', font=('Arial', '20'), fg = 'red',
command = endTrade)

#Configure Button Sizes

button1.config( height = 3, width = 25 )
button2.config( height = 3, width = 25 )

#Display Buttons On Screen

button1.grid(row=1, column=0, sticky = S, padx=616)
button2.grid(row=2, column=0)

root.mainloop()

Kind Regards

-Spencer

From steve at pearwood.info  Sun Apr 26 13:02:57 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Apr 2015 21:02:57 +1000
Subject: [Tutor] output is all integer when there should be some floats
In-Reply-To: <CALRAYNWgqDM=XNCs+gwSaAXUa9WpfAOPX7CAcBtBPWfhq-=Z1w@mail.gmail.com>
References: <CALRAYNWgqDM=XNCs+gwSaAXUa9WpfAOPX7CAcBtBPWfhq-=Z1w@mail.gmail.com>
Message-ID: <20150426110256.GK5663@ando.pearwood.info>

On Sat, Apr 25, 2015 at 09:18:53PM -0700, Jim Mooney Py3winXP wrote:
> It seems odd to me that there are three tests to see if user input is
> digits - isdecimal, isdigit, isnumeric, but nothing to test for a float
> unless you use a try - except. Or did I miss something?

Yes -- the string tests don't specifically test for valid numbers, only 
digit characters.

If we go back deep into the mists of time, when dinosaurs ruled the 
earth, Python ints were not unlimited in size. If you tried to create an 
integer that was too big, you would get an exception, either an 
OverflowError or a ValueError depending on what you tried to do.

Even today, just because a string is all digits doesn't mean that you 
can successfully turn it into an int. You may run out of memory, if you 
have millions of digits.

The right way to check is a string is numeric is to try to convert it 
into a number and see what happens. The string methods are too strict, 
and will prohibit perfectly good numeric strings:

py> s = '  -123  '
py> s.isdigit()
False
py> int(s)
-123


(In my experience, the isdigit etc. methods are really only useful for 
testing individual characters.)

Instead:

try:
    n = int(s)
except ValueError:
    print("failed")

or similar.


Do you know the difference in meaning between isdigit, isnumeric, and 
isdecimal?


> Anyway, I tried a
> try - except, but I don't see why my output is all integer when I only
> convert to integer if it passes the is_integer test:

That's what you *intended* to do, but it isn't what you did :-)

> user_values = []
> while True:
>     user_input = input("Give me a number: ")
>     if user_input.lower() == 'done': break
>     try:
>         user_input = float(user_input)
>         if user_input.is_integer: user_input = int(user_input)

At the interactive interpreter:

py> x = 23.1
py> x.is_integer  # no brackets
<built-in method is_integer of float object at 0xb7aef950>
py> x.is_integer()  # with brackets
False

Built-in methods and functions are consider "truthy" values, so your 
test user_input.is_integer (without the brackets) is always true and the 
number will always be converted to an int.


Personally, I would not do the conversion like that. The big problem is 
that for sufficiently large integers, floats lose precision:

py> s = '123456789012345678901'
py> int(s)
123456789012345678901
py> int(float(s))
123456789012345683968


Instead, I'd create a helper function that first tries to convert to an 
int, and only if that fails, converts to a float:


def make_number(astring):
    if not isinstance(astring, str):
        raise TypeError('not a string')
    for kind in (int, float):
        try:
            return kind(astring)
        except ValueError:
            pass
    raise ValueError(
        'String {0} is not a supported number.'.format(astring)
        )


You could support more formats if you like, e.g. 0x123 for hex ints, 
complex, fractions, percentages, whatever you wanted. But as a simpler 
string-to-int-or-float function, this works well.



-- 
Steve

From steve at pearwood.info  Sun Apr 26 13:22:53 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Apr 2015 21:22:53 +1000
Subject: [Tutor] Tutor Digest, Vol 134, Issue 89
In-Reply-To: <CAOpmNVEePqfWjo9o2G1gW63jF+nixrg4WbWZM1+R8RVnC05_+A@mail.gmail.com>
References: <mailman.478.1430009022.3679.tutor@python.org>
 <CAOpmNVEePqfWjo9o2G1gW63jF+nixrg4WbWZM1+R8RVnC05_+A@mail.gmail.com>
Message-ID: <20150426112253.GL5663@ando.pearwood.info>

Hi Juanald, or Jon if you prefer,

You're still replying to the digest, which means we're still getting six 
or eight pages of messages we've already seen.

My answer to your question is below:


On Sat, Apr 25, 2015 at 11:02:56PM -0400, Juanald Reagan wrote:
> Sorry for not providing all the relevant info, let me provide some
> additional details:
> 
> When I run this code:
> 
>     from ipwhois import IPWhois
>     file=open('ip.txt', 'r')
>     ipaddy=file.read()
>     obj = IPWhois(ipaddy)
>     results = [obj.lookup()]
>     print results [0]
> 
> I receive this output:
> 
> Jons-computer:whois-0.7 2 jon$ python pythonwhois.py
> 
> {'asn_registry': 'arin', 'asn_date': '', 'asn_country_code': 'US', 'raw':
> None, 'asn_cidr': '8.8.8.0/24', 'raw_referral': None, 'query': '8.8.8.8',
[snip output]

Awesome! That's the information we needed to see. IPWhois() returns a 
dictionary of {key: value} pairs. So we can extract the fields you want 
like this:

obj = IPWhois(ipaddy)
registry = obj['asn_registry']
description = obj['description']


If you insist on using a list with indexed values, you can do this:

obj = IPWhois(ipaddy)
results = [obj['asn_registry'], obj['description']]
registry = results[0]
description = results[1]

but in my opinion that's silly since you already have the information in 
the obj dictionary, copying it into the results list is just a waste of 
time.

Note that this will *not* work:

obj = IPWhois(ipaddy)
results = list(obj.values())
registry = results[ ???? ]    # What index should I use?
description = results[ ???? ]


because dictionaries are unordered, and you don't know what order the 
values will be returned. Depending on the version of Python you are 
using, it might even be a different order every time you run the 
program.


-- 
Steve

From steve at pearwood.info  Sun Apr 26 13:30:26 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Apr 2015 21:30:26 +1000
Subject: [Tutor] Python tkinter. Opening another script from main window
	stop main window from functioning. Looking for Help
In-Reply-To: <CAAAQYPcHjgPjqLaqRO5jy0FA_Ag0fnL0vit=2Nuj1kLk3F6DwQ@mail.gmail.com>
References: <CAAAQYPcHjgPjqLaqRO5jy0FA_Ag0fnL0vit=2Nuj1kLk3F6DwQ@mail.gmail.com>
Message-ID: <20150426113025.GM5663@ando.pearwood.info>

On Sat, Apr 25, 2015 at 11:23:44PM -0400, Spencer For Friends wrote:
> Hi all. I'm new to Python and I'm trying my best to learn, but I'm really
> struggling with some problems.

You've picked a *very* hard problem to solve. I can tell you what's 
wrong, but I can't tell you how to fix it. I know it can be fixed, but 
I've never had to do it before.

[Thinking aloud... Maybe the subprocess module? ... ]

[snip code]

> def callback():
>     execfile("test.py")

Here is your problem: execfile will run a Python program, but it 
has to wait for that program to finish before it can continue. So your 
callback is waiting for the test.py program to finish, which I guess 
means closing its windows.

It you want to have test.py run independently of this window, you cannot 
use execfile.

Sorry I can't solve your problem, but at least you now understand it.


-- 
Steve

From alan.gauld at btinternet.com  Sun Apr 26 13:57:57 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 26 Apr 2015 12:57:57 +0100
Subject: [Tutor] REPL format
In-Reply-To: <CALRAYNX9FGOjOprReR+94xQegeWVHML4KDTMKUug3YkwT=ErhQ@mail.gmail.com>
References: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
 <mhhcb8$7vr$1@ger.gmane.org>
 <CALRAYNX9FGOjOprReR+94xQegeWVHML4KDTMKUug3YkwT=ErhQ@mail.gmail.com>
Message-ID: <mhijs3$6go$1@ger.gmane.org>

On 26/04/15 02:28, Jim Mooney wrote:

> Another question - why does the first assignment work but not the second. I
> can see it's a syntax error but if Py can unpack in the first case why
> can't it unpack the same thing in the second?

I'm not sure what you expect it to unpack. Its already a variable 
pointing at a tuple without the *. What do you expect the * to do?

>>>> a, *b = 'ham', 'eggs', 'spam'
>>>> a
> 'ham'
>>>> b
> ['eggs', 'spam']
>>>> *b = 'eggs', 'spam'
> SyntaxError: starred assignment target must be in a list or tuple

 >>> b = 'eggs', 'spam'
 >>> b
('eggs', 'spam')



-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From steve at pearwood.info  Sun Apr 26 14:05:28 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Apr 2015 22:05:28 +1000
Subject: [Tutor] REPL format
In-Reply-To: <mhijs3$6go$1@ger.gmane.org>
References: <CALRAYNVz-Vz5gZk0_oArfqaGRPsCe3-ctOocPs=Y9yJBwbWeSA@mail.gmail.com>
 <mhhcb8$7vr$1@ger.gmane.org>
 <CALRAYNX9FGOjOprReR+94xQegeWVHML4KDTMKUug3YkwT=ErhQ@mail.gmail.com>
 <mhijs3$6go$1@ger.gmane.org>
Message-ID: <20150426120528.GN5663@ando.pearwood.info>

On Sun, Apr 26, 2015 at 12:57:57PM +0100, Alan Gauld wrote:
> On 26/04/15 02:28, Jim Mooney wrote:
> 
> >Another question - why does the first assignment work but not the second. I
> >can see it's a syntax error but if Py can unpack in the first case why
> >can't it unpack the same thing in the second?
> 
> I'm not sure what you expect it to unpack. Its already a variable 
> pointing at a tuple without the *. What do you expect the * to do?

Well, it could unpack the values of the right and re-pack them on the 
left, except that would be a waste of time and effort :-)


-- 
Steve

From ben+python at benfinney.id.au  Sun Apr 26 14:07:15 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Sun, 26 Apr 2015 22:07:15 +1000
Subject: [Tutor]
 =?utf-8?q?Please_disable_=E2=80=9Cdigest_mode=E2=80=9D_be?=
 =?utf-8?q?fore_participating?=
References: <mailman.399.1429975810.3679.tutor@python.org>
 <CAOpmNVEoS06FaTHnZSx2KwZiMku41rmXQVb82D3r9nvceGXGGw@mail.gmail.com>
 <85lhhfk8f9.fsf_-_@benfinney.id.au>
 <CALRAYNXyqtvLbAodE47T1ndNc9+mPHaky=s1dNVFtBL9y3qj2w@mail.gmail.com>
Message-ID: <85h9s3jdos.fsf@benfinney.id.au>

Jim Mooney <cybervigilante at gmail.com> writes:

> On 25 April 2015 at 18:03, Ben Finney <ben+python at benfinney.id.au> wrote:
>
> > Digest mode should only ever be used if you know for certain you will
> > never be responding to any message.
>
> That brings up a great shortcut if you use gmail. If you select some
> text before reply that's All that is sent.

That doesn't reply to the original message. So it lacks the threading
provided by the ?In-Reply-To? field, since you're not replying to the
original message.

It also lacks the correct Subject field, the correct attribution line,
etc. So, no, I still recommend strongly against responding to digest
messages ? the information simply isn't there to compose a correct reply
message.

Instead, disable digest mode, and only after individual messages start
arriving at your mailbox can you participate properly, by replying to
them.

-- 
 \            ?But it is permissible to make a judgment after you have |
  `\    examined the evidence. In some circles it is even encouraged.? |
_o__)                    ?Carl Sagan, _The Burden of Skepticism_, 1987 |
Ben Finney


From alan.gauld at btinternet.com  Sun Apr 26 14:11:20 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 26 Apr 2015 13:11:20 +0100
Subject: [Tutor] Python tkinter. Opening another script from main window
 stop main window from functioning. Looking for Help
In-Reply-To: <CAAAQYPcHjgPjqLaqRO5jy0FA_Ag0fnL0vit=2Nuj1kLk3F6DwQ@mail.gmail.com>
References: <CAAAQYPcHjgPjqLaqRO5jy0FA_Ag0fnL0vit=2Nuj1kLk3F6DwQ@mail.gmail.com>
Message-ID: <mhikl6$hpc$1@ger.gmane.org>

On 26/04/15 04:23, Spencer For Friends wrote:

> I'm using a tkinter window with a button on it to open another Python
> script. When the button is clicked and the new script loads it opens up
> it's own window over top of my tkinter window. The problem is, when I
> switch back to my tkinter window, none of the buttons are click-able
> anymore. The whole windows is unresponsive.


Steven has explained that this is due to using execfile().
You should virtually never use execfile(). There is nearly
always a better way of doing whatever you want to do.

Since in this case the second script seems to be a Tkinter
program in its own right, it probably has functions that
you can call from your code if you import it as a module.

You might be able to create a new TopLevel window and in itys 
constructor call those functions or set them up as callbacks
on your window. That would be the normal procedure from a GUI.

If you can't do that because the other script is badly written
(or if it were not a Python script)  then you would be better
launching it as a separate process using the subprocess module.

Without knowing more about the exact structure of your code
and what you are trying to do we can't really say more than
that.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From davea at davea.name  Sun Apr 26 21:20:40 2015
From: davea at davea.name (Dave Angel)
Date: Sun, 26 Apr 2015 15:20:40 -0400
Subject: [Tutor]
 =?utf-8?q?Please_disable_=E2=80=9Cdigest_mode=E2=80=9D_be?=
 =?utf-8?q?fore_participating?=
In-Reply-To: <85h9s3jdos.fsf@benfinney.id.au>
References: <mailman.399.1429975810.3679.tutor@python.org>
 <CAOpmNVEoS06FaTHnZSx2KwZiMku41rmXQVb82D3r9nvceGXGGw@mail.gmail.com>
 <85lhhfk8f9.fsf_-_@benfinney.id.au>
 <CALRAYNXyqtvLbAodE47T1ndNc9+mPHaky=s1dNVFtBL9y3qj2w@mail.gmail.com>
 <85h9s3jdos.fsf@benfinney.id.au>
Message-ID: <553D3A88.2070303@davea.name>

On 04/26/2015 08:07 AM, Ben Finney wrote:
> Jim Mooney <cybervigilante at gmail.com> writes:
>
>> On 25 April 2015 at 18:03, Ben Finney <ben+python at benfinney.id.au> wrote:
>>
>>> Digest mode should only ever be used if you know for certain you will
>>> never be responding to any message.
>>
>> That brings up a great shortcut if you use gmail. If you select some
>> text before reply that's All that is sent.
>
> That doesn't reply to the original message. So it lacks the threading
> provided by the ?In-Reply-To? field, since you're not replying to the
> original message.
>
> It also lacks the correct Subject field, the correct attribution line,
> etc. So, no, I still recommend strongly against responding to digest
> messages ? the information simply isn't there to compose a correct reply
> message.
>
> Instead, disable digest mode, and only after individual messages start
> arriving at your mailbox can you participate properly, by replying to
> them.
>

When I used to subscribe here using digest, and reading with 
Thunderbird, I'd see each message as an attachment.  To reply to one, I 
first opened the appropriate attachment, and did a Reply-List to it. 
WOrked well.

I took a quick look, for another forum which I monitor using the digest, 
and it looks like the same approach would still work.  For occasional 
posting.

-- 
DaveA

From cs at zip.com.au  Sun Apr 26 23:15:07 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Mon, 27 Apr 2015 07:15:07 +1000
Subject: [Tutor]
 =?utf-8?q?Please_disable_=E2=80=9Cdigest_mode=E2=80=9D_be?=
 =?utf-8?q?fore_participating?=
In-Reply-To: <553D3A88.2070303@davea.name>
References: <553D3A88.2070303@davea.name>
Message-ID: <20150426211507.GA1117@cskk.homeip.net>

On 26Apr2015 15:20, Dave Angel <davea at davea.name> wrote:
>On 04/26/2015 08:07 AM, Ben Finney wrote:
>>That doesn't reply to the original message. So it lacks the threading
>>provided by the ?In-Reply-To? field, since you're not replying to the
>>original message. [...]
>
>When I used to subscribe here using digest, and reading with 
>Thunderbird, I'd see each message as an attachment.  To reply to one, 
>I first opened the appropriate attachment, and did a Reply-List to it. 
>WOrked well.
>
>I took a quick look, for another forum which I monitor using the 
>digest, and it looks like the same approach would still work.  For 
>occasional posting.

Did you check the digest for Mesaage-ID headers for each message item? Most 
digests lack them and as such, replies cannot be stitched together correctly.

You may have been using a mailer with a "group messages by subject" 
(mis?)feature, which may have merely made it look like it worked well.

Cheers,
Cameron Simpson <cs at zip.com.au>

I swear to god, officer, I'm fixing this bridge. Just go divert traffic.

From cs at zip.com.au  Sun Apr 26 23:10:54 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Mon, 27 Apr 2015 07:10:54 +1000
Subject: [Tutor]
 =?utf-8?q?Please_disable_=E2=80=9Cdigest_mode=E2=80=9D_be?=
 =?utf-8?q?fore_participating?=
In-Reply-To: <85h9s3jdos.fsf@benfinney.id.au>
References: <85h9s3jdos.fsf@benfinney.id.au>
Message-ID: <20150426211054.GA83437@cskk.homeip.net>

On 26Apr2015 22:07, Ben Finney <ben+python at benfinney.id.au> wrote:
>Jim Mooney <cybervigilante at gmail.com> writes:
>> On 25 April 2015 at 18:03, Ben Finney <ben+python at benfinney.id.au> wrote:
>> > Digest mode should only ever be used if you know for certain you will
>> > never be responding to any message.
>>
>> That brings up a great shortcut if you use gmail. If you select some
>> text before reply that's All that is sent.
>
>That doesn't reply to the original message. So it lacks the threading
>provided by the ?In-Reply-To? field, since you're not replying to the
>original message.
>It also lacks [...]

Yes, but it _does_ point an easy way for people from top-posting 
do-not-trim-quotes cultures to adopt the technophile's 
trim-quotes-for-relevance style which is so useful in discussion (versus 
chatter).

Apple Mail also supports this handy "use the selected text for the context 
quote" technique and I think a number of the other OSX based mail programs.

It doesn't cut it for multipoint quote1-reply1 quote2-reply2 messages, but it 
is a great jumping off point for people new to the method.

_If_ the OP has abandoned digest mode, Jim's pointer is very useful.

Before then I agree that it is far less so, but that is because digests are 
very unfortunate.

Cheers,
Cameron Simpson <cs at zip.com.au>

Never belong to any party, always oppose privileged classes and public
plunderers, never lack sympathy with the poor, always remain devoted to
the public welfare, never be satisfied with merely printing news, always
be drastically independent, never be afraid to attack wrong, whether by
predatory plutocracy or predatory poverty. - Joseph Pulitzer, 1907 Speech

From cybervigilante at gmail.com  Mon Apr 27 01:23:21 2015
From: cybervigilante at gmail.com (Jim Mooney Py3winXP)
Date: Sun, 26 Apr 2015 16:23:21 -0700
Subject: [Tutor] output is all integer when there should be some floats
In-Reply-To: <20150426110256.GK5663@ando.pearwood.info>
References: <CALRAYNWgqDM=XNCs+gwSaAXUa9WpfAOPX7CAcBtBPWfhq-=Z1w@mail.gmail.com>
 <20150426110256.GK5663@ando.pearwood.info>
Message-ID: <CALRAYNWSJ_b+MgWtGymYwLOfnd73uwLY1QCTT-=3HnvhGVbVMA@mail.gmail.com>

On 26 April 2015 at 04:02, Steven D'Aprano <steve at pearwood.info> wrote:

>     for kind in (int, float):
>         try:
>             return kind(astring)
>

That puzzled me for a moment until I remembered you can toss functions
around in Python. Something to play with on a Sunday  afternoon ;')

But aren't most languages going in that direction? (Well, maybe not COBOL)

-- 
Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From alexgonzi0204 at gmail.com  Mon Apr 27 03:18:04 2015
From: alexgonzi0204 at gmail.com (alex gonsalez)
Date: Sun, 26 Apr 2015 21:18:04 -0400
Subject: [Tutor] CPU Scheduling
Message-ID: <CAAHz=yrVRRXSOUEC+PuUhJc94jvmRCeLSQtD_BY+qzx8q6FZcw@mail.gmail.com>

Need help trying to implement a CPU scheduling algorithm.I am not even sure
where to start on this. Can someone please guide me and walk me through the
steps for this?

Assignment:
The Simulation.
Simulating the scheduling of a single CPU is a type of discrete event
simulation in which you iterate over discrete steps of time and handle
events as they occur. The simulation continues for a given amount of time
or until all data has been processed.
Add the processes to the ready queue.
 cpu = None
curTime = 0
while ready queue is not empty :
handle events that occur during the current time step curTime = curTime + 1
For this project, the simulation will continue while there are still
processes that need to use the CPU. There are three types of events that
can occur: the CPU is initially empty, the time slice for the current
process on the CPU has expired or the process has completed execution
before the time slice has expired. ? If the CPU is initially empty, select
the next process from the ready queue and assign it to the CPU. 1 CS 112 ?
Spring 2015 Programming Assignment Four ? 2 ? If a process completes
execution, it?s removed from the system and it?s total wait time is added
to a running total. ? If a process has used its time slice, the process is
removed from the CPU and the next process is selected from the ready queue
and assigned to the CPU. The process that was removed is added back to the
ready queue to wait its turn before it can again use the CPU. Note that the
next process has to be dequeued before the current process is added back to
the queue. Text File. The simulation data will be contained in a text file
that has the following format: 2 15 8 35 0 25 10 5 5 5 2 7 12 30 7 10 0 3 8
15 where each line contains information for a single process. The first
value is the priority and the second value is the amount of processing time
required (i.e. the total amount of time the processor needs to use the
CPU). Note that the lower the priority value, the higher the priority.
Assume the first line contains the information for process 1, the second
line for process 2, and so on. The Algorithms. You are to implement two
priority based scheduling algorithms. For the first algorithm, the next
process selected from the ready queue is simply the one with the highest
priority. For the second algorithm, you are to make a slight modification.
Each time a process is put back into the ready queue, after being removed
from the CPU, reduce the priority level by 5. Results. Your program should
produce output similar to the following: Number of processes: 10 Time
slice: 10 Total time: 150 Algorithm 1 Avg wait time: 60.10 Algorithm 2 Avg
wait time: 62.80 To compute the average wait time over all of the
processes, you will need to keep track of how much time each process spends
in the ready queue and then compute the average of those times. Assume that
all processes are started at the exact same time. CS 112 ? Spring 2015
Programming Assignment Four ? 3 Requirements. Your program should be placed
within a driver named cpu.py. Your program should be well structured and
commented appropriately as indicated in the programming style guide
provided on the course web page. Some important points to keep in mind: ? A
linked list implementation of the Priority Queue ADT is provided in the
course directory. ? You must use a top-down design with functions. ? Your
program should read from the user the name of the text file that contains
the simulation data and the length of a time slice (as an integer). ? Use a
variable (cpu) to hold a reference to the process object (your storage
object) for the process that is currently assigned to the cpu. ? In
addition to the curTime variable, you should use a second time variable
that indicates the time when a process needs to be switched off the cpu.
This variable acts as an alarm or the time an alarm goes off to signal an
event. When a process is assigned to the cpu, compute the time when it
should be switched off (current time + time slice or current time + time
remaining for the process). ? To compute the wait time, you will need to
keep track of the current time when the process is added to the ready
queue. Then each time a process is removed from the ready queue, compute
how much time it spent in the queue and add that to the processes total
wait time. ? You will need to use a storage object to store the information
for a single process. It should contain the process number, the priority,
the remaining CPU time required for that process, its total wait time, and
the time it was added to the ready queue. The data in the storage object
must be stored as integer values. ? Each time the process is added back to
the ready queue, you should add the storage objects to the priority queue
and update the remaining CPU time

From alan.gauld at btinternet.com  Mon Apr 27 10:03:55 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 27 Apr 2015 09:03:55 +0100
Subject: [Tutor] CPU Scheduling
In-Reply-To: <CAAHz=yrVRRXSOUEC+PuUhJc94jvmRCeLSQtD_BY+qzx8q6FZcw@mail.gmail.com>
References: <CAAHz=yrVRRXSOUEC+PuUhJc94jvmRCeLSQtD_BY+qzx8q6FZcw@mail.gmail.com>
Message-ID: <mhkqh8$mp8$1@ger.gmane.org>

On 27/04/15 02:18, alex gonsalez wrote:
> Need help trying to implement a CPU scheduling algorithm.I am not even sure
> where to start on this. Can someone please guide me and walk me through the
> steps for this?

Your assignment gives a pretty thorough description of what needs
to be done.

Maybe you can start by drafting a pseudo code description of
the main scheduling algorithm?

Also you could think about the data structures you need. It
mentions a linked list although in Python I'd think a normal
list would do just as well.

What variables are you going to need?
What historic data are you going to store? And how will
that be represented?

It describes two separate algorithms you need to implement.
Can you define those in pseudo code?

>
> Assignment:
> The Simulation.
> Simulating the scheduling of a single CPU is a type of discrete event
> simulation in which you iterate over discrete steps of time and handle
> events as they occur. The simulation continues for a given amount of time
> or until all data has been processed....


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From gebrekirstos2015 at gmail.com  Mon Apr 27 11:32:16 2015
From: gebrekirstos2015 at gmail.com (Gebrekirstos G/meskel)
Date: Mon, 27 Apr 2015 12:32:16 +0300
Subject: [Tutor] plz help me
Message-ID: <CAKgeKd_82raVtm=2m=gFVACPrnzNFRpTfCdAhXdyFFhqxkPg4A@mail.gmail.com>

Hi guys:

I need help for

consume .NET web service in python code from Ubuntu OS

thanks alot

G/kirstos

From wombingsac at gmail.com  Mon Apr 27 12:37:54 2015
From: wombingsac at gmail.com (Whom Isac)
Date: Mon, 27 Apr 2015 20:37:54 +1000
Subject: [Tutor] Adding consecutive numbers
Message-ID: <CADXqDX9hc8qiPu0qkiZgmHDP06etjraL5aQg4ayyQQ16us7bQQ@mail.gmail.com>

Hi, I am trying to build a python mini program to solve a math problem . I
wanted my program to ask two number from the operator and it can add those
number as a integer but as consecutive number in range. For example, if
num1 entry =1 & num2 entry = 100 , the program should be adding number from
1 to 100 together(which should equal to 5050). I thought that I could use
range() to use it for any given input from the user. However, there are few
argumentation error and I don't know why my bool function did not work in
while loop. Is there any way to make the program more concise.
I have uploaded my code file below. Please, note that I am fairly new to
programming and donot use complex modules, therefore, suggest me where I
was wrong with the code. I have checked for indentation error, however,
there were no error. So, I don't have any idea about the error.
Thanks.
-------------- next part --------------

##Goal: Building a math program, which allows addition of two numbers in range in consequitive
## sequence e.g. 1+2...+n

if __name__=='__main__':
    interact()

def iteract():
    print('''Welcome to My new Math program!! 
    With this program, you can find the sum of any consequitive numbers.''')
    print('So Just add your numbers in following spaces')
    x =int(input('Please enter your first number: '))
    y =int(input('Please enter your second number: '))
    while True:
        if x<y:
            z = adding_sum_in(x,y)
        else:
            break
    print z


def find_range(x, y):
    x = []
    y = []
    while True:
##        print x.isdigit()
##        print y.isdigit()
       if x.isdigit() == 'True':
            for num in x:
                x.append(num)
       if y.isdigit() == 'True':
            for num in y:
                y.append(num) 
        break
    return R = range({0},{1}).format(x,y)


def adding_sum_in_range(x, y):
    c= find_range(x,y)
    Total_sum = 0
    for i in c:
        Total_sum += i
        return Total_sum
    print(str(Total_sum))
    

'''This is for simple addition function of two numbers:

def addition(x, y):
    num1=(x)
    num2=(y)
return num1+num2

    '''

From alan.gauld at btinternet.com  Mon Apr 27 14:13:31 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 27 Apr 2015 13:13:31 +0100
Subject: [Tutor] plz help me
In-Reply-To: <CAKgeKd_82raVtm=2m=gFVACPrnzNFRpTfCdAhXdyFFhqxkPg4A@mail.gmail.com>
References: <CAKgeKd_82raVtm=2m=gFVACPrnzNFRpTfCdAhXdyFFhqxkPg4A@mail.gmail.com>
Message-ID: <mhl958$990$1@ger.gmane.org>

On 27/04/15 10:32, Gebrekirstos G/meskel wrote:
> Hi guys:
>
> I need help for
>
> consume .NET web service in python code from Ubuntu OS

OK, But to help you we need you to help us.

What does this web service look like?
What version of Python are you using?
What have tyou tried so far , if anything?
What experience of programming 9ion Python) do you have?

Web services come in all kinds of shapes and sizes
from XMLRPC to SOAP to RESTful services.

give us a clue.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Mon Apr 27 14:16:14 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 27 Apr 2015 13:16:14 +0100
Subject: [Tutor] Adding consecutive numbers
In-Reply-To: <CADXqDX9hc8qiPu0qkiZgmHDP06etjraL5aQg4ayyQQ16us7bQQ@mail.gmail.com>
References: <CADXqDX9hc8qiPu0qkiZgmHDP06etjraL5aQg4ayyQQ16us7bQQ@mail.gmail.com>
Message-ID: <mhl9ac$990$2@ger.gmane.org>

On 27/04/15 11:37, Whom Isac wrote:

> num1 entry =1 & num2 entry = 100 , the program should be adding number from
> 1 to 100 together(which should equal to 5050).

> I have uploaded my code file below.

Infortunately we can't see it.
Since it is presumably quite short please just send it
in the body of your email.

Also include the full error text that you refer to,

Also tell us the Python version and OS you are using.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From davea at davea.name  Mon Apr 27 14:41:58 2015
From: davea at davea.name (Dave Angel)
Date: Mon, 27 Apr 2015 08:41:58 -0400
Subject: [Tutor] Adding consecutive numbers
In-Reply-To: <CADXqDX9hc8qiPu0qkiZgmHDP06etjraL5aQg4ayyQQ16us7bQQ@mail.gmail.com>
References: <CADXqDX9hc8qiPu0qkiZgmHDP06etjraL5aQg4ayyQQ16us7bQQ@mail.gmail.com>
Message-ID: <553E2E96.3000509@davea.name>

On 04/27/2015 06:37 AM, Whom Isac wrote:
> Hi, I am trying to build a python mini program to solve a math problem . I
> wanted my program to ask two number from the operator and it can add those
> number as a integer but as consecutive number in range. For example, if
> num1 entry =1 & num2 entry = 100 , the program should be adding number from
> 1 to 100 together(which should equal to 5050). I thought that I could use
> range() to use it for any given input from the user. However, there are few
> argumentation error and I don't know why my bool function did not work in
> while loop. Is there any way to make the program more concise.
> I have uploaded my code file below. Please, note that I am fairly new to
> programming and donot use complex modules, therefore, suggest me where I
> was wrong with the code. I have checked for indentation error, however,
> there were no error. So, I don't have any idea about the error.
> Thanks.
>

You really shouldn't use attachments on this list, since many cannot see 
them.  I happen to be able to, so I'll try to comment.

In addition, each time you start a new thread, you should specify what 
Python version you're  trying to use, and what OS.

I never heard of an "argumentation error" so you'll really have to show 
the exact error.  Just copy/paste it from your user shell.  And exact 
for syntax errors, show the complete traceback.

Your code has many errors in it, and is unnecessarily complex.  At its 
simplest, you could use some simple algebra, and write:

     x =int(input('Please enter your first number: '))
     y =int(input('Please enter your second number: '))
     print (x+y) * (y-x + 1) / 2

But if you really have to do the sum, then you need to build a list, and 
sum it.  That's not very hard either, since range() returns a list, and 
the sum() function is built-in.

But now, let's look at your code, and identify a few of the problems 
with it.

Your second line calls function interact(), which isn't defined yet. 
And in fact, when it is defined, it is spelled differently.  Put your 
top-level code (those two lines, anyway) at the *end* of the file, after 
the function(s) it needs are defined.

In function iteract (spelled inconsistently), you have a while True 
loop, with a break in the else clause.  But if x<y, then you'll loop 
forever, since neither one changes, and if x>=y, you'll hit the break 
without defining z, so print z will throw an exception.

Also in that function you call a function called adding_sum_in(), but 
there's no function by that name.


In function find_range(), the first thing you do is trash your 
arguments.  So whatever else is in that function probably doesn't matter 
much.

In the loop:
             for num in x:
                 x.append(num)

you're modifying the same thing you're looping over.  Not generally a 
good idea, so I have no idea if it'll do anything useful or not. 
Probably not.

     return R = range({0},{1}).format(x,y)

is a syntax error.

def adding_sum_in_range(x, y):
     c= find_range(x,y)
     Total_sum = 0
     for i in c:
         Total_sum += i
         return Total_sum

You have an indentation problem there, as this will return the first 
time through the loop.

def addition(x, y):
     num1=(x)
     num2=(y)
return num1+num2

Another indentation problem.

-- 
DaveA

From breamoreboy at yahoo.co.uk  Mon Apr 27 14:58:51 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Mon, 27 Apr 2015 13:58:51 +0100
Subject: [Tutor] Adding consecutive numbers
In-Reply-To: <553E2E96.3000509@davea.name>
References: <CADXqDX9hc8qiPu0qkiZgmHDP06etjraL5aQg4ayyQQ16us7bQQ@mail.gmail.com>
 <553E2E96.3000509@davea.name>
Message-ID: <mhlbqb$sl5$1@ger.gmane.org>

On 27/04/2015 13:41, Dave Angel wrote:
> On 04/27/2015 06:37 AM, Whom Isac wrote:
>
> But if you really have to do the sum, then you need to build a list, and
> sum it.  That's not very hard either, since range() returns a list, and
> the sum() function is built-in.
>

range() only returns a list in Python 2 but it doesn't matter here as 
sum() accepts any iterable, not just a list.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From steve at pearwood.info  Mon Apr 27 15:45:10 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 27 Apr 2015 23:45:10 +1000
Subject: [Tutor] Adding consecutive numbers
In-Reply-To: <CADXqDX9hc8qiPu0qkiZgmHDP06etjraL5aQg4ayyQQ16us7bQQ@mail.gmail.com>
References: <CADXqDX9hc8qiPu0qkiZgmHDP06etjraL5aQg4ayyQQ16us7bQQ@mail.gmail.com>
Message-ID: <20150427134510.GP5663@ando.pearwood.info>

Hi, and welcome!

My answers are below.

On Mon, Apr 27, 2015 at 08:37:54PM +1000, Whom Isac wrote:
> Hi, I am trying to build a python mini program to solve a math problem . I
> wanted my program to ask two number from the operator and it can add those
> number as a integer but as consecutive number in range. For example, if
> num1 entry =1 & num2 entry = 100 , the program should be adding number from
> 1 to 100 together(which should equal to 5050). I thought that I could use
> range() to use it for any given input from the user. However, there are few
> argumentation error and I don't know why my bool function did not work in
> while loop. Is there any way to make the program more concise.
> I have uploaded my code file below. Please, note that I am fairly new to
> programming and donot use complex modules, therefore, suggest me where I
> was wrong with the code. I have checked for indentation error, however,
> there were no error. So, I don't have any idea about the error.
> Thanks.

Thank you very much for sending the code you have so far! Unfortunately, 
I wish I had good news but I don't -- nearly everything about it is 
wrong.

You have a good idea of what you want the program to do, and you have 
made a good attempt at splitting it into separate functions, but sadly 
the details are wrong and that prevents your code from working. Let's 
see if we can fix that.

The first, and most important, thing is that Python can only run code it 
has already seen. So if I write this:

do_something()  # Call the function.

def do_something():  # Define the function.
    print("Working really hard...")


it will fail because at the time Python tries to call do_something() it 
doesn't exist yet. This is your very first problem:

> if __name__=='__main__':
>     interact()
> 
> def iteract():

When you try to call interact(), the function doesn't exist!

Rule 1: Put your function definitions at the top of the file. Put the 
if __name__ == '__main__' block at the bottom of the file. That way, by 
the time Python reaches that block and calls the functions, they will 
have already been created and are ready to use.

Now, let's think about good program design. A well-designed program will 
separate the program logic from the user-interface. In other words, the 
part of the program which calculates the result should be kept apart 
from the part of the program which communicates with the user. That 
makes it much easier to test each half separately, in case of any 
problems.

So, let's start with a simple function that takes two integers as 
arguments, and adds all the numbers between then. Python gives you the 
tools to make this easy:


---- cut here -----

def add_range(start, end):
    """Add the numbers between start and end inclusive."""
    the_range = range(start, end+1)
    return sum(the_range)


print(add_range(1, 7))  # Should print 28
print(add_range(8, 20))  # Should print 128

---- cut here ----


There is a function, sum(), which is used for adding up a sequence of 
numbers, and another function, range(), which creates a sequence of 
numbers from start to one less than the end. So we add one more to the 
end, create the range, then use sum() to add up the numbers.

Now let's have another function to get a number from the user. We will 
use that function to get the starting number, then re-use it to get the 
ending number, then finally pass those two number to the add_range() 
function we created above.


---- cut here ----

def get_user_number(message):
    """Get an int from the user."""
    while True:
        # Keep trying forever.
        answer = input(message)
        if answer.isdigit():
            return int(answer)
        else:
            print("Sorry, that is not a number!")


start = get_user_number("Please enter your starting number: ")
end = get_user_number("Please enter your ending number: ")

print("start is", start, "; end is", end)
print(add_range(start, end))

---- cut here ----


And that's nearly all you need!


Any questions?



-- 
Steve

From steve at pearwood.info  Mon Apr 27 15:50:28 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 27 Apr 2015 23:50:28 +1000
Subject: [Tutor] plz help me
In-Reply-To: <CAKgeKd_82raVtm=2m=gFVACPrnzNFRpTfCdAhXdyFFhqxkPg4A@mail.gmail.com>
References: <CAKgeKd_82raVtm=2m=gFVACPrnzNFRpTfCdAhXdyFFhqxkPg4A@mail.gmail.com>
Message-ID: <20150427135028.GQ5663@ando.pearwood.info>

On Mon, Apr 27, 2015 at 12:32:16PM +0300, Gebrekirstos G/meskel wrote:
> Hi guys:
> 
> I need help for
> 
> consume .NET web service in python code from Ubuntu OS

Show us the code you have, and the error it is producing, and well try 
to help.


-- 
Steve

From dyoo at hashcollision.org  Mon Apr 27 19:13:32 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Mon, 27 Apr 2015 10:13:32 -0700
Subject: [Tutor] CPU Scheduling
In-Reply-To: <mhkqh8$mp8$1@ger.gmane.org>
References: <CAAHz=yrVRRXSOUEC+PuUhJc94jvmRCeLSQtD_BY+qzx8q6FZcw@mail.gmail.com>
 <mhkqh8$mp8$1@ger.gmane.org>
Message-ID: <CAGZAPF6-g2DHi5RbC2WcrN+2k+F2KGvSfZg2HG26yxnQqs3K3Q@mail.gmail.com>

> On 27/04/15 02:18, alex gonsalez wrote:
>>
>> Need help trying to implement a CPU scheduling algorithm.

Hi Alex,

Unfortunately, this is way out of scope for Python-tutor; I think
you'll be better off discussing with your classmates and professor.
You'll get more productive answers that way.

One reason that here is probably not the right place for this question
is because, essentially, you're asking a classroom full of programming
beginners, many of us who are still learning how to do things like
loops, variables, and values, how to do a hard-core operating system
homework exercise.

Another reason is that most academic institutions have an honor code
which prohibits or discourages certain activities.  As an example of
one, see a random one, like the GMU CS honor code:

    http://cs.gmu.edu/wiki/pmwiki.php/HonorCode/CSHonorCodePolicies

From wolfrage8765 at gmail.com  Mon Apr 27 20:03:06 2015
From: wolfrage8765 at gmail.com (WolfRage)
Date: Mon, 27 Apr 2015 14:03:06 -0400
Subject: [Tutor] CPU Scheduling
In-Reply-To: <CAGZAPF6-g2DHi5RbC2WcrN+2k+F2KGvSfZg2HG26yxnQqs3K3Q@mail.gmail.com>
References: <CAAHz=yrVRRXSOUEC+PuUhJc94jvmRCeLSQtD_BY+qzx8q6FZcw@mail.gmail.com>
 <mhkqh8$mp8$1@ger.gmane.org>
 <CAGZAPF6-g2DHi5RbC2WcrN+2k+F2KGvSfZg2HG26yxnQqs3K3Q@mail.gmail.com>
Message-ID: <553E79DA.6080104@gmail.com>

On 04/27/2015 01:13 PM, Danny Yoo wrote:
>> On 27/04/15 02:18, alex gonsalez wrote:
>>>
>>> Need help trying to implement a CPU scheduling algorithm.
Can I recommend that you read this: 
http://www.dabeaz.com/coroutines/Coroutines.pdf
About half way through it has a Excellent example of how an OS schedules 
processes.


From dfarooqi at lakeheadu.ca  Mon Apr 27 20:10:15 2015
From: dfarooqi at lakeheadu.ca (Durrayshehwar Farooqi)
Date: Mon, 27 Apr 2015 14:10:15 -0400
Subject: [Tutor] MTIE calculation
Message-ID: <CAP80Q67sj1LmkxYCoKD+QQf7Xk6+tHUSgOEk-Kg0eDBbbAeYDQ@mail.gmail.com>

Hello,

Need help with how to calculate MTIE using Python. I have imported numpy
and allantools, please help.

Thanks

-- 

Kind Regards;
*Durray *

From alan.gauld at btinternet.com  Mon Apr 27 20:36:32 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 27 Apr 2015 19:36:32 +0100
Subject: [Tutor] MTIE calculation
In-Reply-To: <CAP80Q67sj1LmkxYCoKD+QQf7Xk6+tHUSgOEk-Kg0eDBbbAeYDQ@mail.gmail.com>
References: <CAP80Q67sj1LmkxYCoKD+QQf7Xk6+tHUSgOEk-Kg0eDBbbAeYDQ@mail.gmail.com>
Message-ID: <mhlvjd$3df$1@ger.gmane.org>

On 27/04/15 19:10, Durrayshehwar Farooqi wrote:

> Need help with how to calculate MTIE using Python. I have imported numpy
> and allantools, please help.

You probably need to tell us exactly what MTIE is and how it works.
You also need to tell us which Python version, which OS and show
us any code you have written already.

This list is for people learning Python and its standard library,
don't assume we know anything about your particular area of study.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From oscar.j.benjamin at gmail.com  Tue Apr 28 01:19:26 2015
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Tue, 28 Apr 2015 00:19:26 +0100
Subject: [Tutor] Python tkinter. Opening another script from main window
 stop main window from functioning. Looking for Help
In-Reply-To: <CAAAQYPcHjgPjqLaqRO5jy0FA_Ag0fnL0vit=2Nuj1kLk3F6DwQ@mail.gmail.com>
References: <CAAAQYPcHjgPjqLaqRO5jy0FA_Ag0fnL0vit=2Nuj1kLk3F6DwQ@mail.gmail.com>
Message-ID: <CAHVvXxSO=hhrxcJp3pHU0K+=96Y_KcUT7cuJVJJ2y4u8Bmef_w@mail.gmail.com>

On 26 April 2015 at 04:23, Spencer For Friends <smarugg at gmail.com> wrote:
> Hi all. I'm new to Python and I'm trying my best to learn, but I'm really
> struggling with some problems.
>
> I'm using a tkinter window with a button on it to open another Python
> script. When the button is clicked and the new script loads it opens up
> it's own window over top of my tkinter window. The problem is, when I
> switch back to my tkinter window, none of the buttons are click-able
> anymore. The whole windows is unresponsive. The click animation on the
> button doesn't even function. Any help to resolve this would be greatly
> appreciated. Here is my code.

Hi Spencer,

The problem is that you're trying to run a long running task within
your applications event loop. You have to understand that the main
loop in a GUI program looks something like this:

while True:
    event = get_event_from_queue()
    if event == button_pressed:
        call_button_callback()
    elif event == key_pressed:
        respond_to_keypress()
    elif event == close_button_clicked:
        close_windows()
        break
   # etc.

Your callback function takes a long time to run and during that time
the event loop is still waiting for call_button_callback() to finish.
The result is that it doesn't respond to anything during that time.

You can test the same effect with a simpler program:

from Tkinter import Tk, Button, S
from tkMessageBox import showinfo

def callback():
    total = sum(1 for _ in xrange(10**8)) # <-- slow
    showinfo(str(total))

root = Tk()

button1 = Button(text='Click me', command=callback)
button1.config(height=3, width=25)
button1.grid(row=1, column=0, sticky=S)

root.mainloop()

When you run this program and click the button it will freeze for 5-10
seconds while running the slow callback() function. If you click
something during this time then your click will go into the event
queue. The event loop will retrieve that click message once it has
finished waiting for the callback function to finish. You can test
this by clicking the 'Click me' button and then clicking the close
button before it has finished. As soon as the callback finishes the
program will close.

The solution to this is to use threads or subprocesses. On the face of
it this is quite simple but actually writing multi-threaded code is
quite tricky. Here's how to modify the above program to run the slow
callback function in a thread:

from Tkinter import Tk, Button, S
from tkMessageBox import showinfo
from threading import Thread

def callback_threaded():
    Thread(target=callback).start()

def callback():
    total = sum(1 for _ in xrange(10**8)) # <-- slow
    showinfo(str(total))

root = Tk()

button1 = Button(text='Click me', command=callback_threaded)
button1.config(height=3, width=25)
button1.grid(row=1, column=0, sticky=S)

root.mainloop()

This program will create a separate execution thread to run the
callback. It's quite simple if you just want to run execfile in
parallel with your GUI. Where it gets trickier is if you need the
threads to interact and you need to pass data between them.


--
Oscar

From jon.engle at gmail.com  Tue Apr 28 04:14:06 2015
From: jon.engle at gmail.com (Juanald Reagan)
Date: Mon, 27 Apr 2015 22:14:06 -0400
Subject: [Tutor] pip install M2crypto
Message-ID: <CAOpmNVEWVuPcJUPyFxZ2-+82bTLH22Sp5BS1ouO8aKnk-r0ZZA@mail.gmail.com>

Good Evening,

 I am trying to install the M2crypto package via pip and receive an error.
Python version is 2.7.4, any ideas on how to fix the SWIG error?

Jon$ sudo -H pip install M2crypto

/Library/Python/2.7/site-packages/pip-6.1.1-py2.7.egg/pip/_vendor/requests/packages/urllib3/util/ssl_.py:79:
InsecurePlatformWarning: A true SSLContext object is not available. This
prevents urllib3 from configuring SSL appropriately and may cause certain
SSL connections to fail. For more information, see
https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning
.

  InsecurePlatformWarning

Collecting M2crypto

/Library/Python/2.7/site-packages/pip-6.1.1-py2.7.egg/pip/_vendor/requests/packages/urllib3/util/ssl_.py:79:
InsecurePlatformWarning: A true SSLContext object is not available. This
prevents urllib3 from configuring SSL appropriately and may cause certain
SSL connections to fail. For more information, see
https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning
.

  InsecurePlatformWarning

  Downloading M2Crypto-0.22.3.tar.gz (74kB)

    100% |????????????????????????????????| 77kB 784kB/s

Installing collected packages: M2crypto

  Running setup.py install for M2crypto

    Complete output from command /usr/bin/python -c "import setuptools,
tokenize;__file__='/private/tmp/pip-build-covxwD/M2crypto/setup.py';exec(compile(getattr(tokenize,
'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))"
install --record /tmp/pip-NWsSZ5-record/install-record.txt
--single-version-externally-managed --compile:

    running install

    running build

    running build_py

    creating build

    creating build/lib.macosx-10.10-intel-2.7

    creating build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/__init__.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/ASN1.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/AuthCookie.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/BIO.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/BN.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/callback.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/DH.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/DSA.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/EC.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/Engine.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/Err.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/EVP.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/ftpslib.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/httpslib.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/m2.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/m2urllib.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/m2urllib2.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/m2xmlrpclib.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/Rand.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/RC4.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/RSA.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/SMIME.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/threading.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/util.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    copying M2Crypto/X509.py -> build/lib.macosx-10.10-intel-2.7/M2Crypto

    creating build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    copying M2Crypto/SSL/__init__.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    copying M2Crypto/SSL/cb.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    copying M2Crypto/SSL/Checker.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    copying M2Crypto/SSL/Cipher.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    copying M2Crypto/SSL/Connection.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    copying M2Crypto/SSL/Context.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    copying M2Crypto/SSL/Session.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    copying M2Crypto/SSL/ssl_dispatcher.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    copying M2Crypto/SSL/SSLServer.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    copying M2Crypto/SSL/timeout.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    copying M2Crypto/SSL/TwistedProtocolWrapper.py ->
build/lib.macosx-10.10-intel-2.7/M2Crypto/SSL

    running build_ext

    building 'M2Crypto.__m2crypto' extension

    swigging SWIG/_m2crypto.i to SWIG/_m2crypto_wrap.c

    swig -python
-I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7
-I/usr/include -I/usr/include/openssl -includeall -modern -o
SWIG/_m2crypto_wrap.c SWIG/_m2crypto.i

    unable to execute swig: No such file or directory

    error: command 'swig' failed with exit status 1



    ----------------------------------------

    Command "/usr/bin/python -c "import setuptools,
tokenize;__file__='/private/tmp/pip-build-covxwD/M2crypto/setup.py';exec(compile(getattr(tokenize,
'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))"
install --record /tmp/pip-NWsSZ5-record/install-record.txt
--single-version-externally-managed --compile" failed with error code 1 in
/private/tmp/pip-build-covxwD/M2crypto

-- 
Cheers,

   Jon

From mitesh.budhabhatti at gmail.com  Tue Apr 28 09:31:04 2015
From: mitesh.budhabhatti at gmail.com (Mitesh H. Budhabhatti)
Date: Tue, 28 Apr 2015 13:01:04 +0530
Subject: [Tutor] Naming conventions
Message-ID: <CADv7osj6Ftza6NakhU2+24HCjCH=9=PzetVUd_wMrqFytAckYw@mail.gmail.com>

Hello Friends,

Can you please suggest good naming conventions/guidelines to following
while writing Python code?  Thanks.

From ctoshea1024 at email.campbell.edu  Tue Apr 28 01:08:06 2015
From: ctoshea1024 at email.campbell.edu (O'Shea, Connor)
Date: Mon, 27 Apr 2015 19:08:06 -0400
Subject: [Tutor] Trouble Downloading 3.2 tutorial
Message-ID: <CAB572PTCR0OB2KfdLSqey-i0eTnhHF=N3cmkCrPAbFynrOVTuw@mail.gmail.com>

Greetings. I have been experiencing difficulty getting my computer to
download the 3.2 python program. My computer has Windows 8 software. What
do you suggest I do to address this problem?

From breamoreboy at yahoo.co.uk  Tue Apr 28 09:38:32 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Tue, 28 Apr 2015 08:38:32 +0100
Subject: [Tutor] Naming conventions
In-Reply-To: <CADv7osj6Ftza6NakhU2+24HCjCH=9=PzetVUd_wMrqFytAckYw@mail.gmail.com>
References: <CADv7osj6Ftza6NakhU2+24HCjCH=9=PzetVUd_wMrqFytAckYw@mail.gmail.com>
Message-ID: <mhnddo$ju4$1@ger.gmane.org>

On 28/04/2015 08:31, Mitesh H. Budhabhatti wrote:
> Hello Friends,
>
> Can you please suggest good naming conventions/guidelines to following
> while writing Python code?  Thanks.
>

PEP 8 - Style Guide for Python Code at 
https://www.python.org/dev/peps/pep-0008/

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From alan.gauld at btinternet.com  Tue Apr 28 09:51:52 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 28 Apr 2015 08:51:52 +0100
Subject: [Tutor] Trouble Downloading 3.2 tutorial
In-Reply-To: <CAB572PTCR0OB2KfdLSqey-i0eTnhHF=N3cmkCrPAbFynrOVTuw@mail.gmail.com>
References: <CAB572PTCR0OB2KfdLSqey-i0eTnhHF=N3cmkCrPAbFynrOVTuw@mail.gmail.com>
Message-ID: <mhne6m$35t$1@ger.gmane.org>

On 28/04/15 00:08, O'Shea, Connor wrote:
> Greetings. I have been experiencing difficulty getting my computer to
> download the 3.2 python program. My computer has Windows 8 software. What
> do you suggest I do to address this problem?


You don't say what kind of "trouble" nor which distribution of
Python you are trying to download.

If its the official python.org one then, as a Windows user I
suggest you try the ActiveState  site since their version
includes many extra Windows features.

Also you say Python v3.2 however the latest version is v3.4.
Unless you have a strong reason to use 3.2 I suggest you
get 3.4 instead, any 3.2 code should run under 3.4.

If you are trying to download one of the "super Pythons"
like Anaconda then I can't help and suggest you ask on
their user fora.

If none of that helps come back to us with a more detailed
description of exactly what you are trying to do, where,
what happens, and any error messages you see.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Tue Apr 28 09:54:45 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 28 Apr 2015 08:54:45 +0100
Subject: [Tutor] pip install M2crypto
In-Reply-To: <CAOpmNVEWVuPcJUPyFxZ2-+82bTLH22Sp5BS1ouO8aKnk-r0ZZA@mail.gmail.com>
References: <CAOpmNVEWVuPcJUPyFxZ2-+82bTLH22Sp5BS1ouO8aKnk-r0ZZA@mail.gmail.com>
Message-ID: <mhnec2$35t$2@ger.gmane.org>

On 28/04/15 03:14, Juanald Reagan wrote:
> Good Evening,
>
>   I am trying to install the M2crypto package via pip and receive an error.
> Python version is 2.7.4, any ideas on how to fix the SWIG error?

Do you have SWIG installed? It should be in your repo.


>
>      unable to execute swig: No such file or directory
>
>      error: command 'swig' failed with exit status 1


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From paradox at pobox.com  Tue Apr 28 10:51:57 2015
From: paradox at pobox.com (Paradox)
Date: Tue, 28 Apr 2015 16:51:57 +0800
Subject: [Tutor] How to output dictionary data to CSV file
Message-ID: <553F4A2D.8030500@pobox.com>

I have some data structured like this:

{'B002':'NRP 2014','B003':'HBB 2015'}

Basically account numbers and project names, each account number has a 
project name.  I represent it in a dictionary because that seemed the 
best way to keep the account numbers and project names together.  I want 
to save that information to a file, CSV seemed the easiest format 
(though I am open to suggestions if there is a better way!).  I expected 
I could write a function that would create a CSV file that looks like this:

B002,NRP 2014
B003,HBB 2015

I thought the DictWriter method of the CSV module should do the trick so 
wrote this:

def write_fqas(fqa_csv,fqa_dict):
     with open('fqa_csv','w') as csvfile:
         writer = csv.DictWriter(csvfile,fieldnames=['FQA','Description']
         writer.writerows(fqa_dict)

This didn't yield the results I was looking for, instead it raises

ValueError: dict contains fields not in fieldnames: 'B', '0', '0', '2'

It seems to be parsing through the key of the first item in the 
dictionary rather than simply saving it to the CSV file as the first 
field on a line (like I expected).  Obviously there is something about 
how csv.DictWriter works that I don't understand.

Any assistance is appreciated.

thomas
==============================
Thomas C. Hicks, MD, MPH
Training Manager, Gansu Gateway
Lanzhou, Gansu, PR China

From paradox at pobox.com  Tue Apr 28 11:00:34 2015
From: paradox at pobox.com (Paradox)
Date: Tue, 28 Apr 2015 17:00:34 +0800
Subject: [Tutor] How to output dictionary data to CSV file
In-Reply-To: <553F4A2D.8030500@pobox.com>
References: <553F4A2D.8030500@pobox.com>
Message-ID: <553F4C32.8000002@pobox.com>

How rude of me, I neglected to note I am using Python 3.4.3.

On 04/28/2015 04:51 PM, Paradox wrote:
> I have some data structured like this:
>
> {'B002':'NRP 2014','B003':'HBB 2015'}
>
> Basically account numbers and project names, each account number has a 
> project name.  I represent it in a dictionary because that seemed the 
> best way to keep the account numbers and project names together.  I 
> want to save that information to a file, CSV seemed the easiest format 
> (though I am open to suggestions if there is a better way!).  I 
> expected I could write a function that would create a CSV file that 
> looks like this:
>
> B002,NRP 2014
> B003,HBB 2015
>
> I thought the DictWriter method of the CSV module should do the trick 
> so wrote this:
>
> def write_fqas(fqa_csv,fqa_dict):
>     with open('fqa_csv','w') as csvfile:
>         writer = csv.DictWriter(csvfile,fieldnames=['FQA','Description']
>         writer.writerows(fqa_dict)
>
> This didn't yield the results I was looking for, instead it raises
>
> ValueError: dict contains fields not in fieldnames: 'B', '0', '0', '2'
>
> It seems to be parsing through the key of the first item in the 
> dictionary rather than simply saving it to the CSV file as the first 
> field on a line (like I expected).  Obviously there is something about 
> how csv.DictWriter works that I don't understand.
>
> Any assistance is appreciated.
>
> thomas
> ==============================
> Thomas C. Hicks, MD, MPH
> Training Manager, Gansu Gateway
> Lanzhou, Gansu, PR China


From __peter__ at web.de  Tue Apr 28 11:30:54 2015
From: __peter__ at web.de (Peter Otten)
Date: Tue, 28 Apr 2015 11:30:54 +0200
Subject: [Tutor] How to output dictionary data to CSV file
References: <553F4A2D.8030500@pobox.com>
Message-ID: <mhnk0f$41f$1@ger.gmane.org>

Paradox wrote:

> I have some data structured like this:
> 
> {'B002':'NRP 2014','B003':'HBB 2015'}
> 
> Basically account numbers and project names, each account number has a
> project name.  I represent it in a dictionary because that seemed the
> best way to keep the account numbers and project names together.  I want
> to save that information to a file, CSV seemed the easiest format
> (though I am open to suggestions if there is a better way!).  I expected
> I could write a function that would create a CSV file that looks like
> this:
> 
> B002,NRP 2014
> B003,HBB 2015
> 
> I thought the DictWriter method of the CSV module should do the trick so
> wrote this:
> 
> def write_fqas(fqa_csv,fqa_dict):
>      with open('fqa_csv','w') as csvfile:
>          writer = csv.DictWriter(csvfile,fieldnames=['FQA','Description']
>          writer.writerows(fqa_dict)
> 
> This didn't yield the results I was looking for, instead it raises
> 
> ValueError: dict contains fields not in fieldnames: 'B', '0', '0', '2'
> 
> It seems to be parsing through the key of the first item in the
> dictionary rather than simply saving it to the CSV file as the first
> field on a line (like I expected).  Obviously there is something about
> how csv.DictWriter works that I don't understand.

DictWriter expects a sequence of dicts where the keys are the column names. 
Example:

>>> import csv
>>> import sys
>>> data = [
... {"FQA": "B002", "Description": "NRP 2014"},
... {"FQA": "B003", "Description": "HBB 2015"},
... ]
>>> writer = csv.DictWriter(sys.stdout, fieldnames=["FQA", "Description"])
>>> writer.writerows(data)
B002,NRP 2014
B003,HBB 2015

As you want to write both keys and values as a column you can pass the dict 
items() to a normal csv.writer:

>>> data = {'B002':'NRP 2014','B003':'HBB 2015'}
>>> writer = csv.writer(sys.stdout)
>>> writer.writerows(data.items())
B002,NRP 2014
B003,HBB 2015

> How rude of me, I neglected to note I am using Python 3.4.3.

And now you're top-posting to make it even worse ;)



From paradox at pobox.com  Tue Apr 28 12:07:17 2015
From: paradox at pobox.com (Thomas C. Hicks)
Date: Tue, 28 Apr 2015 18:07:17 +0800
Subject: [Tutor] How to output dictionary data to CSV file :p:
In-Reply-To: <mhnk0f$41f$1@ger.gmane.org>
References: <553F4A2D.8030500@pobox.com> <mhnk0f$41f$1@ger.gmane.org>
Message-ID: <553F5BD5.2000704@pobox.com>



On 04/28/2015 05:30 PM, Peter Otten wrote:
>>>> >>>data = {'B002':'NRP 2014','B003':'HBB 2015'}
>>>> >>>writer = csv.writer(sys.stdout)
>>>> >>>writer.writerows(data.items())
> B002,NRP 2014
> B003,HBB 2015
That is exactly what I was looking for!  Thanks, apparently my knowledge 
deficit is in understanding dictionary methods.
>
>> >How rude of me, I neglected to note I am using Python 3.4.3.
> And now you're top-posting to make it even worse;)
Lesson learned!

thomas


From alan.gauld at btinternet.com  Tue Apr 28 15:43:09 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 28 Apr 2015 14:43:09 +0100
Subject: [Tutor] How to output dictionary data to CSV file
In-Reply-To: <553F4A2D.8030500@pobox.com>
References: <553F4A2D.8030500@pobox.com>
Message-ID: <mho2pa$vlb$1@ger.gmane.org>

On 28/04/15 09:51, Paradox wrote:

> to save that information to a file, CSV seemed the easiest format

You could consider JSON too.
JSON looks a lot like a Python dictionary of strings so is
almost a perfect match to your data. The json module is in
the standard library.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From sage at cyberguerrilla.org  Tue Apr 28 11:55:46 2015
From: sage at cyberguerrilla.org (Sage Hack)
Date: Tue, 28 Apr 2015 05:55:46 -0400
Subject: [Tutor] Pythonic review (descriptors)
Message-ID: <553F5922.1040701@cyberguerrilla.org>

I'm looking for somebody willing to review parts of this code
https://github.com/SageHack/cloud-buster and let me know what is not
Pythonic :P

I want to improve my Python coding skills but I'm not sure exactly what
to study next.

Right now I'm trying to use descriptors correctly and I'd like to know
if this is about right
https://github.com/SageHack/cloud-buster/tree/master/bust/descriptor

Thanks :)

From alan.gauld at btinternet.com  Tue Apr 28 16:21:44 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 28 Apr 2015 15:21:44 +0100
Subject: [Tutor] Pythonic review (descriptors)
In-Reply-To: <553F5922.1040701@cyberguerrilla.org>
References: <553F5922.1040701@cyberguerrilla.org>
Message-ID: <mho51l$dt3$1@ger.gmane.org>

On 28/04/15 10:55, Sage Hack wrote:
> I'm looking for somebody willing to review parts of this code
> https://github.com/SageHack/cloud-buster and let me know what is not
> Pythonic :P

 > https://github.com/SageHack/cloud-buster/tree/master/bust/descriptor

The thing that jumps out to me is your use of class variables to hold a 
dictionary of instance responses based on the instance ID. That
pattern looks like this, and you use it in every class:

class SomeClass:
     classvar = {}

     def __init__(self,id):
        self.id = id
     def __get__(self...):
        v = getSomeValue()
        sel.classvar[self.id] = v

Normally you'd store instance specific data in the instance
itself not in a class variable. also you overwrite the
classvariable entry for each instance every time you call
the get(). Is that really what you want?

The other thing is that you should have docstrings for
both the classes and methods.

Finally, and not Python specific, You have several classes
sharing the same 'ID' data - self.domain - that's usually
a bad OOP smell. Only one class should be mastering any
given type of  data, so maybe your other classes are
really methods of whichever is the master class? Particularly
since they don't have any explicit methods (also a bad OOP
smell) of their own.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Tue Apr 28 16:27:39 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 28 Apr 2015 15:27:39 +0100
Subject: [Tutor] Pythonic review (descriptors)
In-Reply-To: <553F5922.1040701@cyberguerrilla.org>
References: <553F5922.1040701@cyberguerrilla.org>
Message-ID: <mho5co$kju$1@ger.gmane.org>

On 28/04/15 10:55, Sage Hack wrote:
> I'm looking for somebody willing to review parts of this code
> https://github.com/SageHack/cloud-buster and let me know what is not
> Pythonic :P

> https://github.com/SageHack/cloud-buster/tree/master/bust/descriptor

Another point re the PageTitle class:

class PageTitle(object):

     titles = {}

     def __init__(self, url, host=None):
         self.url = url
         self.host = host

     def __get__(self, obj=None, objtype=None):...

     @property
     def id(self):
         if self.host:
             return self.url+':'+self.host
         else:
             return self.url


There is not much point in calculating the id each time,
it could simply be set in the init(). You never change
the url or host.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From steve at pearwood.info  Tue Apr 28 17:15:19 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 29 Apr 2015 01:15:19 +1000
Subject: [Tutor] Naming conventions
In-Reply-To: <CADv7osj6Ftza6NakhU2+24HCjCH=9=PzetVUd_wMrqFytAckYw@mail.gmail.com>
References: <CADv7osj6Ftza6NakhU2+24HCjCH=9=PzetVUd_wMrqFytAckYw@mail.gmail.com>
Message-ID: <20150428151518.GV5663@ando.pearwood.info>

On Tue, Apr 28, 2015 at 01:01:04PM +0530, Mitesh H. Budhabhatti wrote:
> Hello Friends,
> 
> Can you please suggest good naming conventions/guidelines to following
> while writing Python code?  Thanks.

Most important rule of all: names should be descriptive and 
understandable, not too short or cryptic, not so long that they are 
painful to use. Very common names may be abbreviated. Names should be 
easy to say aloud.

    # Good names
    length, len, map, format

    # Bad names
    a, the_thing_we_process, szty

Avoid "funny" or meaningless names:

    pizza = 23
    homework = 5
    print (pizza > homework)


It is acceptable to use standard one-letter variable names in 
generic functions, especially for algebraic (maths) functions and 
short utility functions, e.g.:

    i, j, k: integer loop variables
    m, n: other integers
    x, y: floats
    z: complex numbers
    s: string or set
    d: dict
    L: list  (don't use l because it can look like 1)
    o: object
    u, v: vectors, arrays, sets

are common choices. But don't over-use one-letter names.

Otherwise, names should be self-descriptive:

    # Bad
    L = get_customers()  # list of customers

    # Good
    customers = get_customers()

Use plurals for lists, sets or dicts of some data type, and the singular 
for individual data types. E.g.:

    names = ['John', 'Mary', 'Fred', 'Sue']
    for name in names:
        process(name)


Functions and methods should be verbs or verb-phrases in all lowercase, 
for example:

    expand() sort() lift() prepare_database() create_factory()

Variables holding data values should be nouns:

   page count header footer server client factory

(Watch out for words which can be both a noun and a verb, like count.)

Classes should be nouns with initial capitals:

    Car Engine Animal HTTPServer

and instances should be lowercase:

    server = HTTPServer()

The exception is if the class is a "small" primitive or simple type, 
like built-ins int, str, dict, list etc. But even then, you may choose 
to use Initial Capitals instead.

Modules should follow the all-lowercase name. If possible, modules 
should describe what they are about:

    math string io unicodedata

but it is also acceptable for modules to have an arbitrary name which 
you just have to learn:

    pillow flask zope fabric nose



Does this help?


-- 
Steve

From diliupg at gmail.com  Tue Apr 28 17:38:46 2015
From: diliupg at gmail.com (diliup gabadamudalige)
Date: Tue, 28 Apr 2015 21:08:46 +0530
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
Message-ID: <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>

---------- Forwarded message ----------
From: diliup gabadamudalige <diliupg at gmail.com>
Date: Tue, Apr 28, 2015 at 6:22 PM
Subject: circular movement in pygame
To: pygame-users at seul.org


Looking at the code on this page lines 47 & 48

http://programarcadegames.com/python_examples/show_file.php?file=sprite_circle_movement.py

is there a way to do
self.rect.x +*= some value*
self.rect.y += some value

rather than

self.rect.x = self.radius * math.sin(self.angle) + self.center_x
self.rect.y = self.radius * math.cos(self.angle) + self.center_y

?

I tired it in the code attached and strangely it works ok but only OUTSIDE
THE class. When I implement the exact code in a class it does something
weird.  I can't find where I have gone wrong.

Please help.

Many thanks in advance.

Diliup Gabadamudalige


**********************************************************************************************
This e-mail is confidential. It may also be legally privileged. If you are
not the intended recipient or have received it in error, please delete it
and all copies from your system and notify the sender immediately by return
e-mail. Any unauthorized reading, reproducing, printing or further
dissemination of this e-mail or its contents is strictly prohibited and may
be unlawful. Internet communications cannot be guaranteed to be timely,
secure, error or virus-free. The sender does not accept liability for any
errors or omissions.
**********************************************************************************************




-- 
Diliup Gabadamudalige

http://www.diliupg.com
http://soft.diliupg.com/

**********************************************************************************************
This e-mail is confidential. It may also be legally privileged. If you are
not the intended recipient or have received it in error, please delete it
and all copies from your system and notify the sender immediately by return
e-mail. Any unauthorized reading, reproducing, printing or further
dissemination of this e-mail or its contents is strictly prohibited and may
be unlawful. Internet communications cannot be guaranteed to be timely,
secure, error or virus-free. The sender does not accept liability for any
errors or omissions.
**********************************************************************************************
-------------- next part --------------
import sys, os, pygame, itertools
from math import sin,cos,pi, radians
from pygame.locals import *

os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (50,50) #Set window position

pygame.init()
clock = pygame.time.Clock()
FPS = 1000

SCREENW = 800   #screen width
SCREENH = 740   #screen height

BLACK = (0, 0, 0)
BLUE = (0, 0, 255)
ORANGE = (128, 100, 30)
FONT1= "Cookie-Regular.ttf"

SCREEN = pygame.display.set_mode((SCREENW, SCREENH), 0, 32) #display screen
clock = pygame.time.Clock()

#-------------------------------------------------------------------------------
def maketext(msg,fontsize, colour = ORANGE, font = FONT1):
    mafont = pygame.font.Font(font, fontsize)
    matext = mafont.render(msg, True, colour)
    matext = matext.convert_alpha()
    return matext

#-------------------------------------------------------------------------------
def print_info():
    """"""
    textcos = maketext(str(round(obj.rect.x, 2)) + "   " + str(round(obj.rect.y, 2)), 30)
    SCREEN.blit(textcos, (obj.rect.x, obj.rect.y + 30))

#-------------------------------------------------------------------------------
class object_factory(pygame.sprite.Sprite):

    def __init__(self, imagelist, xpos = 0, ypos = 0, speedx = 0, speedy = 0, value = 0):
        """Constructor"""
        pygame.sprite.Sprite.__init__(self)
        self.name = ""
        self.frame = 0
        self.imagelist = imagelist
        self.image = imagelist[self.frame]
        self.mask = pygame.mask.from_surface(self.image) # pixelmask
        self.rect = self.image.get_rect()
        self.rect.x = xpos
        self.rect.y = ypos
        self.speedx = speedx
        self.speedy = speedy
        self.timer = 0
        self.timerlimit = 10

        #----------------------------------------------------------------------
    def move(self):  # wallsprites, Herosprite, looptime
        self.rect.x += self.speedx
        self.rect.y += self.speedy

    #----------------------------------------------------------------------
    def update(self):
        """"""
        self.image = self.imagelist[self.frame]
        if self.timer >= self.timerlimit:
            self.frame += 1
            if self.frame >= len(self.imagelist):
                self.frame = 0
            self.timer = 0
        self.timer += 1

plat = pygame.image.load("plt0.png").convert_alpha()
star = pygame.image.load("gemp0.png").convert_alpha()
box = pygame.image.load("crateB.png").convert_alpha()

platforms = pygame.sprite.Group()
boxes = pygame.sprite.Group()

From alan.gauld at btinternet.com  Tue Apr 28 19:50:59 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 28 Apr 2015 18:50:59 +0100
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
Message-ID: <mhoha0$jqk$1@ger.gmane.org>

On 28/04/15 16:38, diliup gabadamudalige wrote:
> ---------- Forwarded message ----------
> From: diliup gabadamudalige <diliupg at gmail.com>
> Date: Tue, Apr 28, 2015 at 6:22 PM
> Subject: circular movement in pygame
> To: pygame-users at seul.org

It's good that you tried the python-game list for a
pygame question. But if pygame-users can't give a
definitive answer then its even less likely that the
tutor list will. Although you might need to allow
a full 24 hours to get answers, email is not an
instant delivery mechanism.

> Looking at the code on this page lines 47 & 48
>
> http://programarcadegames.com/python_examples/show_file.php?file=sprite_circle_movement.py

I didn't look at the code in that tutorial, but...

> is there a way to do
> self.rect.x +*= some value*
> self.rect.y += some value

Yes, that's just normal Python syntax. It adds/multiplies
the current value of self.rect with "some value"...

> rather than
>
> self.rect.x = self.radius * math.sin(self.angle) + self.center_x
> self.rect.y = self.radius * math.cos(self.angle) + self.center_y

But its unlikely to have the same effect as this since the
above two lines are calculating a new value based on radius,
angle, and centre rather than one based on the current
values of self.rect

> I tired it in the code attached and strangely it works ok but only OUTSIDE
> THE class. When I implement the exact code in a class it does something
> weird.  I can't find where I have gone wrong.

I can't see your code but are you sure you are using self in
all the appropriate places in your class based code?


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From oscar.j.benjamin at gmail.com  Tue Apr 28 20:28:07 2015
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Tue, 28 Apr 2015 19:28:07 +0100
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
Message-ID: <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>

On 28 April 2015 at 16:38, diliup gabadamudalige <diliupg at gmail.com> wrote:
>
> Looking at the code on this page lines 47 & 48
>
> http://programarcadegames.com/python_examples/show_file.php?file=sprite_circle_movement.py
>
> is there a way to do
> self.rect.x +*= some value*
> self.rect.y += some value
>
> rather than
>
> self.rect.x = self.radius * math.sin(self.angle) + self.center_x
> self.rect.y = self.radius * math.cos(self.angle) + self.center_y

There's no way to do that. The second version ignores the previous
value of self.rect.x/y.

I'm going to guess that the angle has only changed by a small amount
delta_angle between iterations in which case there would be a way to
do it approximately.

The real question is just why though? The second version is correct
and will be correct for ever. The first version would only be
approximately correct and over time you'd probably find that the
position would drift so that the ball was effectively at a different
radius.

In any case if
     x = r * sin(theta)
then
    dx/dt = r * cos(theta) * dtheta/dt.
Since
    y = r * cos(theta) that's
    dy/dt = x * dtheta/dt.
So you could update y approximately with:
    y += x * dtheta/dt * deltat
where deltat is your timestep. In your code that would be:
    self.rect.x += self.rect.y * self.speed
    self.rect.y -= self.rect.x * self.speed

Really what you have now is better though.

From oscar.j.benjamin at gmail.com  Tue Apr 28 21:00:09 2015
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Tue, 28 Apr 2015 20:00:09 +0100
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
Message-ID: <CAHVvXxSo_swXiY+5HLaWYeeTxg9qBN97s3SVzd45rBM=bMSQxQ@mail.gmail.com>

On 28 April 2015 at 19:37, diliup gabadamudalige <diliupg at gmail.com> wrote:
>
> I thank all those who responded to my question
>
> Here is the code that I had written.
>
> When updating is applied to a surface object the rotation works but when it
> is applied through a class to an object it goes wrong in about 3 rotations.
> As far as I can see the code is the same. What is wrong? If you can correct
> some code and show me would help.

Your code is too long and complicated for me to read through it all.
You should simplify your problem before posting it somewhere like
this. Make a simpler program that does something similar but without
all the pygame stuff. For example your program might just loop through
printing out the positions of the object at different times e.g.:

# game.py
#
# This program simulates a ball moving at constant speed
# in a two dimensional space.
#

# Initial position of ball
xpos = 0
ypos = 0

# Horizontal and vertical speed
xspeed = 1
yspeed = 2

# Timestep
deltat = 0.125

# Run through 10 iterations of simulation
for n in range(10):
    # Update state
    xpos += xspeed * deltat
    ypos += yspeed * deltat

    # Output current state
    print('Position = (%.3f, %.3f)' % (xpos, ypos))

$ python game.py  # Show the output
Position = (0.125, 0.250)
Position = (0.250, 0.500)
Position = (0.375, 0.750)
Position = (0.500, 1.000)
Position = (0.625, 1.250)
Position = (0.750, 1.500)
Position = (0.875, 1.750)
Position = (1.000, 2.000)
Position = (1.125, 2.250)
Position = (1.250, 2.500)

Once you have made a simpler program carefully explain what it is that
you want it to do and show us how what it does is different. Don't
expect people on this list to download your code and run it.

Also please put your code in the email and not in an attachment and
please reply back to the tutor list rather than directly to me.


--
Oscar

From diliupg at gmail.com  Tue Apr 28 20:37:37 2015
From: diliupg at gmail.com (diliup gabadamudalige)
Date: Wed, 29 Apr 2015 00:07:37 +0530
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
Message-ID: <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>

I thank all those who responded to my question

Here is the code that I had written.

When updating is applied to a surface object the rotation works but when it
is applied through a class to an object it goes wrong in about 3 rotations.
As far as I can see the code is the same. What is wrong? If you can correct
some code and show me would help.

On Tue, Apr 28, 2015 at 11:58 PM, Oscar Benjamin <oscar.j.benjamin at gmail.com
> wrote:

> On 28 April 2015 at 16:38, diliup gabadamudalige <diliupg at gmail.com>
> wrote:
> >
> > Looking at the code on this page lines 47 & 48
> >
> >
> http://programarcadegames.com/python_examples/show_file.php?file=sprite_circle_movement.py
> >
> > is there a way to do
> > self.rect.x +*= some value*
> > self.rect.y += some value
> >
> > rather than
> >
> > self.rect.x = self.radius * math.sin(self.angle) + self.center_x
> > self.rect.y = self.radius * math.cos(self.angle) + self.center_y
>
> There's no way to do that. The second version ignores the previous
> value of self.rect.x/y.
>
> I'm going to guess that the angle has only changed by a small amount
> delta_angle between iterations in which case there would be a way to
> do it approximately.
>
> The real question is just why though? The second version is correct
> and will be correct for ever. The first version would only be
> approximately correct and over time you'd probably find that the
> position would drift so that the ball was effectively at a different
> radius.
>
> In any case if
>      x = r * sin(theta)
> then
>     dx/dt = r * cos(theta) * dtheta/dt.
> Since
>     y = r * cos(theta) that's
>     dy/dt = x * dtheta/dt.
> So you could update y approximately with:
>     y += x * dtheta/dt * deltat
> where deltat is your timestep. In your code that would be:
>     self.rect.x += self.rect.y * self.speed
>     self.rect.y -= self.rect.x * self.speed
>
> Really what you have now is better though.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Diliup Gabadamudalige

http://www.diliupg.com
http://soft.diliupg.com/

**********************************************************************************************
This e-mail is confidential. It may also be legally privileged. If you are
not the intended recipient or have received it in error, please delete it
and all copies from your system and notify the sender immediately by return
e-mail. Any unauthorized reading, reproducing, printing or further
dissemination of this e-mail or its contents is strictly prohibited and may
be unlawful. Internet communications cannot be guaranteed to be timely,
secure, error or virus-free. The sender does not accept liability for any
errors or omissions.
**********************************************************************************************
-------------- next part --------------
import sys, os, pygame, itertools
from math import sin,cos,pi, radians
from pygame.locals import *

os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (50,50) #Set window position

pygame.init()
clock = pygame.time.Clock()
FPS = 1000

SCREENW = 800   #screen width
SCREENH = 740   #screen height

BLACK = (0, 0, 0)
BLUE = (0, 0, 255)
ORANGE = (128, 100, 30)
FONT1= "Cookie-Regular.ttf"

SCREEN = pygame.display.set_mode((SCREENW, SCREENH), 0, 32) #display screen
clock = pygame.time.Clock()

#-------------------------------------------------------------------------------
def maketext(msg,fontsize, colour = ORANGE, font = FONT1):
    mafont = pygame.font.Font(font, fontsize)
    matext = mafont.render(msg, True, colour)
    matext = matext.convert_alpha()
    return matext

#-------------------------------------------------------------------------------
def print_info():
    """"""
    textcos = maketext(str(round(obj.rect.x, 2)) + "   " + str(round(obj.rect.y, 2)), 30)
    SCREEN.blit(textcos, (obj.rect.x, obj.rect.y + 30))

#-------------------------------------------------------------------------------
class object_factory(pygame.sprite.Sprite):

    def __init__(self, imagelist, xpos, ypos, speedx = 0, speedy = 0, value = 0):
        """Constructor"""
        pygame.sprite.Sprite.__init__(self)
        self.name = ""
        self.frame = 0
        self.imagelist = imagelist
        self.image = imagelist[self.frame]
        self.mask = pygame.mask.from_surface(self.image) # pixelmask
        self.rect = self.image.get_rect()
        self.rect.x = xpos
        self.rect.y = ypos
        #self.speedx = speedx
        #self.speedy = speedy
        self.timer = 0
        self.timerlimit = 10

        #----------------------------------------------------------------------
    #def move(self):  # wallsprites, Herosprite, looptime
        #self.rect.x += self.speedx
        #self.rect.y += self.speedy

    #----------------------------------------------------------------------
    def update(self):
        """"""
        self.image = self.imagelist[self.frame]
        if self.timer >= self.timerlimit:
            self.frame += 1
            if self.frame >= len(self.imagelist):
                self.frame = 0
            self.timer = 0
        self.timer += 1

plat = pygame.image.load("plt0.png").convert_alpha()
star = pygame.image.load("gemp0.png").convert_alpha()
#box = pygame.image.load("crateB.png").convert_alpha()

platforms = pygame.sprite.Group()
boxes = pygame.sprite.Group()

rotcenx = SCREENW/2
rotceny = SCREENH/2

radius = 200
angle = radians(90)  #pi/4 # starting angle 45 degrees
omega = radians(5) #Angular velocity

m = rotcenx + radius * cos(angle) #Starting position x
n = rotceny - radius * sin(angle) #Starting position y

for _ in itertools.repeat(None, 1):
    madyax = SCREENW/2
    madyay = SCREENH/2

    araya = 200
    konaya = radians(180)  #pi/4 # starting angle 45 degrees
    konika_pravegaya = radians(5) #Angular velocity

    a = madyax + (araya * cos(konaya)) #Starting position x
    b = madyay - (araya * sin(konaya)) #Startinh position y

    plat = object_factory([plat], a, b)
    plat.araya = araya
    plat.konaya = konaya
    plat.kp = konika_pravegaya


    platforms.add(plat)

while True:
    ms = clock.tick(FPS)  # milliseconds passed since last frame
    #looptime = milliseconds / 1000.0 # seconds passed since last frame

    SCREEN.fill((BLACK))

    pygame.draw.circle(SCREEN, BLUE, (SCREENW / 2, SCREENH / 2), 5)

    ##-----------------------------------------------------------
    SCREEN.blit(star, (m, n)) # Draw current x,y

    angle = angle + omega # New angle, we add angular velocity
    m = m + radius * omega * cos(angle + pi / 2) # New x
    n = n - radius * omega * sin(angle + pi / 2) # New y
    ##-----------------------------------------------------------
    # show object anchored to center of rotation
    pygame.draw.line(SCREEN, ORANGE, (rotcenx, rotceny), (m, n))

    text = maketext(str(radius), 30)
    SCREEN.blit(text, (m, n - 40))

    text = maketext((str(round(m, 2)) + "  " + str(round(n, 2))), 30)
    SCREEN.blit(text, (m, n + 40)) # Draw current x,y

    ##------------------------------------------------------------------
    for plat in platforms:

        plat.konaya = plat.konaya + plat.kp

        plat.rect.x = plat.rect.x + plat.araya * plat.kp * cos(plat.konaya + pi / 2)
        plat.rect.y = plat.rect.y - plat.araya * plat.kp * sin(plat.konaya + pi / 2)
    ##------------------------------------------------------------------------
    pygame.draw.line(SCREEN, ORANGE, (madyax, madyay), (plat.rect.x, plat.rect.y))

    platforms.update()
    platforms.draw(SCREEN)

    pygame.event.pump()
    keys = pygame.key.get_pressed()

    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()

    pygame.display.update()
    pygame.time.wait(100)

From paradox at pobox.com  Tue Apr 28 23:40:55 2015
From: paradox at pobox.com (Thomas C. Hicks)
Date: Wed, 29 Apr 2015 05:40:55 +0800
Subject: [Tutor] How to output dictionary data to CSV file :p:
In-Reply-To: <mho2pa$vlb$1@ger.gmane.org>
References: <553F4A2D.8030500@pobox.com> <mho2pa$vlb$1@ger.gmane.org>
Message-ID: <553FFE67.50008@pobox.com>


On 04/28/2015 09:43 PM, Alan Gauld wrote:
> You could consider JSON too.
> JSON looks a lot like a Python dictionary of strings so is
> almost a perfect match to your data.

Sounds great, I'll check it out.  Thanks!

thomas
==============================
Thomas C. Hicks, MD, MPH
Training Manager, Gansu Gateway
Lanzhou, Gansu, PR China

From davea at davea.name  Wed Apr 29 01:16:26 2015
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Apr 2015 19:16:26 -0400
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
Message-ID: <554014CA.90601@davea.name>

On 04/28/2015 02:37 PM, diliup gabadamudalige wrote:
> I thank all those who responded to my question
>
> Here is the code that I had written.
>
> When updating is applied to a surface object the rotation works but when it
> is applied through a class to an object it goes wrong in about 3 rotations.
> As far as I can see the code is the same. What is wrong? If you can correct
> some code and show me would help.
>

By top-posting, you're messing up the readability of your response.  And 
by trying to use an attachment, you're messing up a large portion of the 
people reading this thread.

Post a simplified example, inline in your message, and *following* any 
quote you're using.

If your symptom is that the data diverges eventually from the intended 
trajectory, the problem is that you're accumulating errors.  Each point 
you do you're rounding the calculation by storing it in finite 
precision.  After enough roundoffs, the error becomes visible.

If you need to reliably move an object in a circle, you'll want to store 
the location in angular terms, center, radius, and angle.

Then each time around the loop, increment the angle by a non-rounded 
amount, and recalculate the x/y coordinates.


-- 
DaveA

From jugurtha.hadjar at gmail.com  Wed Apr 29 05:06:05 2015
From: jugurtha.hadjar at gmail.com (Jugurtha Hadjar)
Date: Wed, 29 Apr 2015 04:06:05 +0100
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
Message-ID: <55404A9D.5010103@gmail.com>

Hello, all..

I have a class with methods that access a database (SQLite3). I have 
included an excerpt showin reading and writing and would like to know if 
I'm doing it right. (i.e: Is it bad code and what to improve).

Here are some improvements and my rationale (check my thinking):

- Initially, each method had its SQL statement(s) inside, but I grouped 
all statements in a dictionary, with operations as keys, as a class 
'constant' as per previous advice on this mailing list.

- Each method used sqlite3 module on its own, but it was repetitive so I 
put that part in its own method `init_db` that returns a tuple 
consisting in a connection and a cursor.

- Sometimes there was an exception raised, so I used `try` in `init_db`.

- Methods closed the connection themselves, so I used `with` in 
`init_db` instead of `try`, as it would close the connection 
automatically and rollback (I hope I'm not making this up).

Here's the excerpt (`DB_FILES` and `QUERIES` are not included here for 
more clarity).

Thank you.



	def __init__(self, phone):

		# Get preliminary information on user and make them
		# available.

		self.phone = phone
		self.known = self.find()
		
		if self.known:
			self.balance = self.get_balance()
		else:
			self.balance = None

	def init_db(self):
		with sqlite3.connect(self.DB_FILE) as conn:
			return conn, conn.cursor()

	def find(self):
		'''Find the phone in the users database.'''
		
		(__, cursor) = self.init_db()
		try:
			cursor.execute(
				self.QUERIES['FIND_PHONE'],
				(self.phone,)
			)
			found = cursor.fetchone()
			return True if found else False
		except Exception as e:
			return self.ERROR.format(e.args[0])

	def create(self, seed_balance):
		''' Create a database entry for the sender.'''

		conn, cursor = self.init_db()
		try:
			cursor.execute(
				self.QUERIES['CREATE'],
				(self.phone, seed_balance)
			)
			conn.commit()
		except Exception as e:
			return self.ERROR.format(e.args[0])




-- 
~Jugurtha Hadjar,

From cybervigilante at gmail.com  Wed Apr 29 05:58:39 2015
From: cybervigilante at gmail.com (Jim Mooney Py3winXP)
Date: Tue, 28 Apr 2015 20:58:39 -0700
Subject: [Tutor] Function works one time then subsequently fails
Message-ID: <CALRAYNVdOT7+0JwFFqf47Nyc8VFQkBw7QU0He-79fe3he0Yscg@mail.gmail.com>

This is really puzzling me. I'm parsing a string to do some simple math
operations and practice tossing functions around. My parser works on the
first run, then it continually fails on the same input.

"""
Takes the name of a binary math operation and two numbers from input,
repeatedly, and displays the results until done
"""

def add(a, b):
    return a + b

def subtract(a, b):
    return b - a

def minus(a, b):
    return a - b

def multiply(a, b):
    return a * b

def divide(a, b):
    return a / b

operations = {'add': add, '+': add, 'plus': add, 'subtract': subtract,
              '-': minus, 'minus': minus, 'multiply': multiply, '*':
multiply,
              'times': multiply, 'divide': divide, '/': divide,
              'divided': divide}

numbers = []

def test_number(astring):
    """
    Input: A string that should represent a valid int or float. Output:
    An int or float on success. None on failure.
    """
    for make_type in (int, float):
        try:
            return make_type(astring)
        except ValueError:
            pass
    return None

def parse_string(math_string):
    """Input: A math string with a verbal or mathematical operation
    and two valid numbers to operate on. Extra numbers and operations
    are ignored. Output: A tuple containing a function corresponding
    to the operation and the two numbers. Returns None on failure.
    """
    operation = None
    tokens = math_string.split()
    for token in tokens:
        if token in operations:
            operation = operations[token]
        elif test_number(token) != None:
            numbers.append(test_number(token))
        if len(numbers) > 1:
            break
    if operation is None or len(numbers) < 2:
        return None
    else:
        return operation, numbers[0], numbers[1]

REPL
>>> result = parse_string('1 minus 15')
>>> func, number1, number2 = result
>>> func(number1, number2)
-14
>>> result = parse_string('1 minus 15')
>>> print(result)
None
>>> result = parse_string('1 minus 15')
>>> print(result)
None
>>>


-- 
Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From cs at zip.com.au  Wed Apr 29 06:27:25 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Wed, 29 Apr 2015 14:27:25 +1000
Subject: [Tutor] Function works one time then subsequently fails
In-Reply-To: <CALRAYNVdOT7+0JwFFqf47Nyc8VFQkBw7QU0He-79fe3he0Yscg@mail.gmail.com>
References: <CALRAYNVdOT7+0JwFFqf47Nyc8VFQkBw7QU0He-79fe3he0Yscg@mail.gmail.com>
Message-ID: <20150429042725.GA62479@cskk.homeip.net>

On 28Apr2015 20:58, Jim Mooney Py3winXP <cybervigilante at gmail.com> wrote:
>This is really puzzling me. I'm parsing a string to do some simple math
>operations and practice tossing functions around. My parser works on the
>first run, then it continually fails on the same input.

[...]
>numbers = []
[...]
>def parse_string(math_string):
>    """Input: A math string with a verbal or mathematical operation
>    and two valid numbers to operate on. Extra numbers and operations
>    are ignored. Output: A tuple containing a function corresponding
>    to the operation and the two numbers. Returns None on failure.
>    """
>    operation = None
>    tokens = math_string.split()
>    for token in tokens:
>        if token in operations:
>            operation = operations[token]
>        elif test_number(token) != None:
>            numbers.append(test_number(token))
>        if len(numbers) > 1:
>            break
[...]

At a first glance numbers is a global. It is reset to [] at program start, but 
never again. So you're appending to it forever. I have not investigated further 
as to how that affects your program's flow.

Cheers,
Cameron Simpson <cs at zip.com.au>

There are two ways of dealing with this problem: one is complicated and
messy, and the other is simple and very elegant. We don't have much time
left, so I'll just show you the complicated and messy way.
- Richard Feynman, 1981

From cybervigilante at gmail.com  Wed Apr 29 07:27:21 2015
From: cybervigilante at gmail.com (Jim Mooney Py3winXP)
Date: Tue, 28 Apr 2015 22:27:21 -0700
Subject: [Tutor] Function works one time then subsequently fails
In-Reply-To: <20150429042725.GA62479@cskk.homeip.net>
References: <CALRAYNVdOT7+0JwFFqf47Nyc8VFQkBw7QU0He-79fe3he0Yscg@mail.gmail.com>
 <20150429042725.GA62479@cskk.homeip.net>
Message-ID: <CALRAYNWD5UPjPxVEyUy-ErgEQTo0HsL6Kz47jZ3uErjD-eiLbA@mail.gmail.com>

On 28 April 2015 at 21:27, Cameron Simpson <cs at zip.com.au> wrote:

> At a first glance numbers is a global. It is reset to [] at program start,
> but never again. So you're appending to it forever. I have not investigated
> further as to how that affects your program's flow.
>
> Cheers,
> Cameron Simpson <cs at zip.com.au>
>

Took you less time to find that than me. I, of course, realized I forgot to
empty the number list on each time through the parse loop, After I posted
;')  Seems to work okay otherwise, although criticism of Pythonicity is
welcome. I just wanted to practice tossing functions around. I'll put it
into a user input loop and work it. It won't catch everything. I have to
study regexes for that.

At this point I'm starting to lose track and have to think of better ways
to organize so I recall and understand what I'm doing. I know there are
general tuts on that but that's just reading. Is there a python-specific
tut on it where I could follow actual code along with the interpreter to
reinforce things? Or, what is the official word for
organize-so-you-don't-forget-or-get-confused so I can search google with it?

-- 
Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From mitesh.budhabhatti at gmail.com  Wed Apr 29 08:06:38 2015
From: mitesh.budhabhatti at gmail.com (Mitesh H. Budhabhatti)
Date: Wed, 29 Apr 2015 11:36:38 +0530
Subject: [Tutor] Naming conventions
In-Reply-To: <20150428151518.GV5663@ando.pearwood.info>
References: <CADv7osj6Ftza6NakhU2+24HCjCH=9=PzetVUd_wMrqFytAckYw@mail.gmail.com>
 <20150428151518.GV5663@ando.pearwood.info>
Message-ID: <CADv7osjDKUKiw1fsQNCmvEoVrhTKMwuOmOEUhHjrWcqUteNsQA@mail.gmail.com>

Thank you so much Mark, Steven.  This will definitely help.  I really
appreciate.


On Tue, Apr 28, 2015 at 8:45 PM, Steven D'Aprano <steve at pearwood.info>
wrote:

> On Tue, Apr 28, 2015 at 01:01:04PM +0530, Mitesh H. Budhabhatti wrote:
> > Hello Friends,
> >
> > Can you please suggest good naming conventions/guidelines to following
> > while writing Python code?  Thanks.
>
> Most important rule of all: names should be descriptive and
> understandable, not too short or cryptic, not so long that they are
> painful to use. Very common names may be abbreviated. Names should be
> easy to say aloud.
>
>     # Good names
>     length, len, map, format
>
>     # Bad names
>     a, the_thing_we_process, szty
>
> Avoid "funny" or meaningless names:
>
>     pizza = 23
>     homework = 5
>     print (pizza > homework)
>
>
> It is acceptable to use standard one-letter variable names in
> generic functions, especially for algebraic (maths) functions and
> short utility functions, e.g.:
>
>     i, j, k: integer loop variables
>     m, n: other integers
>     x, y: floats
>     z: complex numbers
>     s: string or set
>     d: dict
>     L: list  (don't use l because it can look like 1)
>     o: object
>     u, v: vectors, arrays, sets
>
> are common choices. But don't over-use one-letter names.
>
> Otherwise, names should be self-descriptive:
>
>     # Bad
>     L = get_customers()  # list of customers
>
>     # Good
>     customers = get_customers()
>
> Use plurals for lists, sets or dicts of some data type, and the singular
> for individual data types. E.g.:
>
>     names = ['John', 'Mary', 'Fred', 'Sue']
>     for name in names:
>         process(name)
>
>
> Functions and methods should be verbs or verb-phrases in all lowercase,
> for example:
>
>     expand() sort() lift() prepare_database() create_factory()
>
> Variables holding data values should be nouns:
>
>    page count header footer server client factory
>
> (Watch out for words which can be both a noun and a verb, like count.)
>
> Classes should be nouns with initial capitals:
>
>     Car Engine Animal HTTPServer
>
> and instances should be lowercase:
>
>     server = HTTPServer()
>
> The exception is if the class is a "small" primitive or simple type,
> like built-ins int, str, dict, list etc. But even then, you may choose
> to use Initial Capitals instead.
>
> Modules should follow the all-lowercase name. If possible, modules
> should describe what they are about:
>
>     math string io unicodedata
>
> but it is also acceptable for modules to have an arbitrary name which
> you just have to learn:
>
>     pillow flask zope fabric nose
>
>
>
> Does this help?
>
>
> --
> Steve
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From cs at zip.com.au  Wed Apr 29 07:40:03 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Wed, 29 Apr 2015 15:40:03 +1000
Subject: [Tutor] Function works one time then subsequently fails
In-Reply-To: <CALRAYNWD5UPjPxVEyUy-ErgEQTo0HsL6Kz47jZ3uErjD-eiLbA@mail.gmail.com>
References: <CALRAYNWD5UPjPxVEyUy-ErgEQTo0HsL6Kz47jZ3uErjD-eiLbA@mail.gmail.com>
Message-ID: <20150429054003.GA43610@cskk.homeip.net>

On 28Apr2015 22:27, Jim Mooney Py3winXP <cybervigilante at gmail.com> wrote:
>On 28 April 2015 at 21:27, Cameron Simpson <cs at zip.com.au> wrote:
>> At a first glance numbers is a global. It is reset to [] at program start,
>> but never again. So you're appending to it forever. I have not investigated
>> further as to how that affects your program's flow.
>
>Took you less time to find that than me. I, of course, realized I forgot to
>empty the number list on each time through the parse loop, After I posted
>;')  Seems to work okay otherwise, although criticism of Pythonicity is
>welcome. I just wanted to practice tossing functions around. I'll put it
>into a user input loop and work it. It won't catch everything. I have to
>study regexes for that.

Basicly, you should almost never have a global variable. There is a host of 
special circumstances where globals solve some specific problems. But by and 
large, don't do it without a very concrete reason.

If numbers had been local to the parse function you would never have been 
bitten by this. There's no need for it to be global; you can return the 
operator and the operands (numbers) easily from the parse function.

>At this point I'm starting to lose track and have to think of better ways
>to organize so I recall and understand what I'm doing. I know there are
>general tuts on that but that's just reading. Is there a python-specific
>tut on it where I could follow actual code along with the interpreter to
>reinforce things? Or, what is the official word for
>organize-so-you-don't-forget-or-get-confused so I can search google with it?

"functional decomposition"?

One rule of thumb is that functions should be short. That way you can generally 
keep their purpose and internal oparations in your head in one go, and the 
whole thing also fits on your screen.

As with all things, sometimes that cannot be reasonably achieved, but it is 
usually so.

We can pick over your code as well if you like. Should we?

Cheers,
Cameron Simpson <cs at zip.com.au>

If this experiment we're doing works, then I will follow up and push it as
hard as possible. And if it doesn't work, I will write a science-fiction
novel where it does work. It's a win-win situation.
- John Cramer on his experiment for possible cuasality violation

From diliupg at gmail.com  Wed Apr 29 09:15:01 2015
From: diliupg at gmail.com (diliup gabadamudalige)
Date: Wed, 29 Apr 2015 12:45:01 +0530
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <554014CA.90601@davea.name>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
Message-ID: <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>

Thanks all for the responses.
Charles Coss? -  yes I can write a simple pygame program that makes a
sprite move in a circle but it may not be the style and order that many may
approve or accept. I consider myself a student. :)
No one has pointed out why the object moves in a circle properly in the bit
of code where it is addressed directly and why it does not when the same
code is applied thru a class.
I know that an object can be made to move around the circumference of a
circle by constantly calculating the point and giving the x and y values

1. x = some code

That is what I used and it worked. I was trying to find how we can do the
same thing by updating the current position by doing

2. x += some code
 Above 1 works. 2 does not. Why is that?

Both the same code. The same variable is used with different names cause
some others were confused when they were the same.

 I hope this time I have answered correctly. No more attachments. (e mail
or otherwise. :) )

From jsolis1 at stedwards.edu  Wed Apr 29 03:24:57 2015
From: jsolis1 at stedwards.edu (Jacqueline G Solis)
Date: Tue, 28 Apr 2015 20:24:57 -0500 (CDT)
Subject: [Tutor] if then statements
In-Reply-To: <187312571.270100.1430270451101.JavaMail.zimbra@stedwards.edu>
Message-ID: <930077296.270499.1430270697882.JavaMail.zimbra@stedwards.edu>

hello,

I keep getting a syntax error. Could you please explain why that happens and how to correct it. 


def main ():
    print( "Welcome to Gonzo Burger!")
    order= int(input("Enter 1 if you want a hamburger,\
    or 2 if you want a cheeseburger:" ))
    if order == 1 :
               print("order: 1")
    else:
               print("Order: 2")

    drink=int(input("Thank you! Next, enter a 1 if you want a Coke,\
    or a 2 if you want a Sprite:")
    if drink == 1 :
              print("Order: 1")
    else:
              print("Order: 2")

    print("Thank you! You ordered:")
    if order == 1:
              print("- Hamburger")
    else:
              print("- Cheeseburger")
    if drink == 1 :
              print("- Coke")
    else:
              print("- Sprite")

main ()
                    

 

-Jackie
p.s: the error happens in the second if statement.

From alan.gauld at btinternet.com  Wed Apr 29 09:48:21 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Apr 2015 08:48:21 +0100
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
Message-ID: <mhq2c2$pr$1@ger.gmane.org>

On 29/04/15 08:15, diliup gabadamudalige wrote:

> 1. x = some code
>
> That is what I used and it worked. I was trying to find how we can do the
> same thing by updating the current position by doing
>
> 2. x += some code
>   Above 1 works. 2 does not. Why is that?


Because they do completely different things!

1 is simply

x = some code

2 is

x = x + some code

In 2 you are adding x to some code.

Of course they don't work the same.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From breamoreboy at yahoo.co.uk  Wed Apr 29 10:01:41 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 29 Apr 2015 09:01:41 +0100
Subject: [Tutor] if then statements
In-Reply-To: <930077296.270499.1430270697882.JavaMail.zimbra@stedwards.edu>
References: <187312571.270100.1430270451101.JavaMail.zimbra@stedwards.edu>
 <930077296.270499.1430270697882.JavaMail.zimbra@stedwards.edu>
Message-ID: <mhq357$hsu$1@ger.gmane.org>

On 29/04/2015 02:24, Jacqueline G Solis wrote:
> hello,
>
> I keep getting a syntax error. Could you please explain why that happens and how to correct it.
>
>
> def main ():
>      print( "Welcome to Gonzo Burger!")
>      order= int(input("Enter 1 if you want a hamburger,\
>      or 2 if you want a cheeseburger:" ))
>      if order == 1 :
>                 print("order: 1")
>      else:
>                 print("Order: 2")
>
>      drink=int(input("Thank you! Next, enter a 1 if you want a Coke,\
>      or a 2 if you want a Sprite:")
>      if drink == 1 :
>                print("Order: 1")
>      else:
>                print("Order: 2")
>
>      print("Thank you! You ordered:")
>      if order == 1:
>                print("- Hamburger")
>      else:
>                print("- Cheeseburger")
>      if drink == 1 :
>                print("- Coke")
>      else:
>                print("- Sprite")
>
> main ()
>
>
>
>
> -Jackie
> p.s: the error happens in the second if statement.
>

No it doesn't :)  That's where it gets found, but the error is actually 
before then, and as a learning exercise I'll let you find it.  Look very 
carefully at "order=..." and "drink=..." and I'm sure you'll spot the 
difference.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From alan.gauld at btinternet.com  Wed Apr 29 10:06:12 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Apr 2015 09:06:12 +0100
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
In-Reply-To: <55404A9D.5010103@gmail.com>
References: <55404A9D.5010103@gmail.com>
Message-ID: <mhq3dh$lnt$1@ger.gmane.org>

On 29/04/15 04:06, Jugurtha Hadjar wrote:

> - Initially, each method had its SQL statement(s) inside, but I grouped
> all statements in a dictionary, with operations as keys, as a class
> 'constant' as per previous advice on this mailing list.

We can't see that in the code you posted.
In principle its an acceptable strategy. A close alternative
would be to name the queries as explicit class variables.
So for example you would use:

cur.execute(self.find_phone_query,(....))

Its less typing and less error prone in that you get a
syntax error on mistyping rather than a run time exception.

> - Each method used sqlite3 module on its own, but it was repetitive so I
> put that part in its own method `init_db` that returns a tuple
> consisting in a connection and a cursor.

That's a common approach.

> - Sometimes there was an exception raised, so I used `try` in `init_db`.
>
> - Methods closed the connection themselves, so I used `with` in
> `init_db` instead of `try`, as it would close the connection
> automatically and rollback (I hope I'm not making this up).

Try/except and with do different things but in this case
you can get away with it. The only loss is that your errors
here are not formatted in the same way as the other messages.

> Here's the excerpt


>      def __init__(self, phone):
>
>          # Get preliminary information on user and make them
>          # available.

Consider using docstrings rather than comments to describe the method
I see you do that below...

>          self.phone = phone
>          self.known = self.find()
>
>          if self.known:
>              self.balance = self.get_balance()
>          else:
>              self.balance = None
>
>      def init_db(self):
>          with sqlite3.connect(self.DB_FILE) as conn:
>              return conn, conn.cursor()
>
>      def find(self):
>          '''Find the phone in the users database.'''
>
>          (__, cursor) = self.init_db()

Don't use the __ 'variable' here, be explicit, it makes
maintenance much easier.

>          try:
>              cursor.execute(
>                  self.QUERIES['FIND_PHONE'],
>                  (self.phone,)
>              )
>              found = cursor.fetchone()
>              return True if found else False
>          except Exception as e:
>              return self.ERROR.format(e.args[0])

Don't catch Exception, it's too wide. Catch the
actual errors that might arise, be as specific as possible.

>      def create(self, seed_balance):
>          ''' Create a database entry for the sender.'''
>
>          conn, cursor = self.init_db()
>          try:
>              cursor.execute(
>                  self.QUERIES['CREATE'],
>                  (self.phone, seed_balance)
>              )
>              conn.commit()
>          except Exception as e:
>              return self.ERROR.format(e.args[0])


as above


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Wed Apr 29 10:08:35 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Apr 2015 09:08:35 +0100
Subject: [Tutor] if then statements
In-Reply-To: <930077296.270499.1430270697882.JavaMail.zimbra@stedwards.edu>
References: <187312571.270100.1430270451101.JavaMail.zimbra@stedwards.edu>
 <930077296.270499.1430270697882.JavaMail.zimbra@stedwards.edu>
Message-ID: <mhq3i0$lnt$2@ger.gmane.org>

On 29/04/15 02:24, Jacqueline G Solis wrote:
> hello,
>
> I keep getting a syntax error.

If you get an error always include the full message text in your 
queries. It helps enormously in finding the problem.

> Could you please explain why that happens and how to correct it.

But in this case its obvious...

> def main ():
>      print( "Welcome to Gonzo Burger!")
>      order= int(input("Enter 1 if you want a hamburger,\
>      or 2 if you want a cheeseburger:" ))
>      if order == 1 :
>                 print("order: 1")
>      else:
>                 print("Order: 2")
>
>      drink=int(input("Thank you! Next, enter a 1 if you want a Coke,\
>      or a 2 if you want a Sprite:")

Count the parentheses in the line above.

> p.s: the error happens in the second if statement.

If you'd sent the error message you wouldn't have to tell us that :-)


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Wed Apr 29 10:21:06 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Apr 2015 09:21:06 +0100
Subject: [Tutor] Function works one time then subsequently fails
In-Reply-To: <CALRAYNVdOT7+0JwFFqf47Nyc8VFQkBw7QU0He-79fe3he0Yscg@mail.gmail.com>
References: <CALRAYNVdOT7+0JwFFqf47Nyc8VFQkBw7QU0He-79fe3he0Yscg@mail.gmail.com>
Message-ID: <mhq49g$4up$1@ger.gmane.org>

On 29/04/15 04:58, Jim Mooney Py3winXP wrote:

> numbers = []

Note that you chose to make this global.

> def parse_string(math_string):
>      """Input: A math string with a verbal or mathematical operation
>      and two valid numbers to operate on. Extra numbers and operations
>      are ignored. Output: A tuple containing a function corresponding
>      to the operation and the two numbers. Returns None on failure.
>      """

General comment. returning a mixture of None and valid data
is a recipe for confusion later. Its better to fail by
raising an exception, say a ValueError for example,
or even create a bespoke error.

>      operation = None
>      tokens = math_string.split()
>      for token in tokens:
>          if token in operations:
>              operation = operations[token]
>          elif test_number(token) != None:
>              numbers.append(test_number(token))
>          if len(numbers) > 1:
>              break
>      if operation is None or len(numbers) < 2:
>          return None
>      else:
>          return operation, numbers[0], numbers[1]
>
> REPL
>>>> result = parse_string('1 minus 15')
>>>> func, number1, number2 = result
>>>> func(number1, number2)
> -14
>>>> result = parse_string('1 minus 15')
>>>> print(result)
> None

You never empty numbers so it already contains >1 numbers.
Your loop breaks. And operation is None.
So you return None.

That's why raising an error with suitable text would be clearer.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Wed Apr 29 10:26:39 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Apr 2015 09:26:39 +0100
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSP51m7O45RwnSM1VY0MnCXH8majshwfC=_md7-YxP07XQ@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>	<CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>	<CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>	<CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>	<554014CA.90601@davea.name>	<CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>	<mhq2c2$pr$1@ger.gmane.org>
 <CAMxbqSP51m7O45RwnSM1VY0MnCXH8majshwfC=_md7-YxP07XQ@mail.gmail.com>
Message-ID: <554095BF.2000208@btinternet.com>

On 29/04/15 09:03, diliup gabadamudalige wrote:
> Thank you Alan. Understood. I already knew that. My question is
>
> How to to do it the second way.
> some code = what?
>
The point is you cannot do it.
The second approach always uses the current value of x.
The first approach may or may not use the current value
of x. If it does not use x then the += style cannot be
made to work (unless you tag a -x on at the end!

x = 42

x += 42-x

Which is just stupid.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


From __peter__ at web.de  Wed Apr 29 10:50:32 2015
From: __peter__ at web.de (Peter Otten)
Date: Wed, 29 Apr 2015 10:50:32 +0200
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
References: <55404A9D.5010103@gmail.com>
Message-ID: <mhq60p$263$1@ger.gmane.org>

Jugurtha Hadjar wrote:

> I have a class with methods that access a database (SQLite3). I have 
> included an excerpt showin reading and writing and would like to know if 
> I'm doing it right. (i.e: Is it bad code and what to improve).
> 
> Here are some improvements and my rationale (check my thinking):
> 
> - Initially, each method had its SQL statement(s) inside, but I grouped 
> all statements in a dictionary, with operations as keys, as a class 
> 'constant' as per previous advice on this mailing list.
> 
> - Each method used sqlite3 module on its own, but it was repetitive so I 
> put that part in its own method `init_db` that returns a tuple 
> consisting in a connection and a cursor.
> 
> - Sometimes there was an exception raised, so I used `try` in `init_db`.
> 
> - Methods closed the connection themselves, so I used `with` in 
> `init_db` instead of `try`, as it would close the connection 
> automatically and rollback (I hope I'm not making this up).
> 
> Here's the excerpt (`DB_FILES` and `QUERIES` are not included here for 
> more clarity).
> 
> Thank you.
> 
> 
> 
>         def __init__(self, phone):
> 
>                 # Get preliminary information on user and make them
>                 # available.
> 
>                 self.phone = phone
>                 self.known = self.find()
>                 
>                 if self.known:
>                         self.balance = self.get_balance()
>                 else:
>>                         self.balance = None
> 
>         def init_db(self):
>                 with sqlite3.connect(self.DB_FILE) as conn:
>                         return conn, conn.cursor()
> 
>         def find(self):
>                 '''Find the phone in the users database.'''
>                 
>                 (__, cursor) = self.init_db()
>                 try:
>                         cursor.execute(
>                                 self.QUERIES['FIND_PHONE'],
>                                 (self.phone,)
>                         )
>                         found = cursor.fetchone()
>                         return True if found else False
>                 except Exception as e:
>                         return self.ERROR.format(e.args[0])
> 
>         def create(self, seed_balance):
>                 ''' Create a database entry for the sender.'''
> 
>                 conn, cursor = self.init_db()
>                 try:
>                         cursor.execute(
>                                 self.QUERIES['CREATE'],
>                                 (self.phone, seed_balan>ce)
>                         )
>                         conn.commit()
>                 except Exception as e:
>                         return self.ERROR.format(e.args[0])

My random observations:

(1) find() and create() look very similar. Try hard to factor out common 
code. You might even combine it into a single method ensure_balance(phone).

(2) According to

https://docs.python.org/dev/library/sqlite3.html#using-the-connection-as-a-context-manager

- the context manager automatically commits
- you can run sql directly on the connection

It might by a good idea to refactor init_db() to just return the connection 
and then use it as

    with self.init_db() as conn:
        return conn.execute(
            self.QUERIES['FIND_PHONE'], 
            (self.phone,)).fetchone() is not None

If you need a cursor you can easily get one from the connection. If you want 
more complex handling later you can always turn init_db() into a 
contextmanager (see
<https://docs.python.org/dev/library/contextlib.html#contextlib.contextmanager> 
). 

(3) Catching Exception is overly broad. You will also catch a typo like

cursor.execute(
    self.QUERIES['CERATE'],
    (self.phone, seed_balance)
)

where the proper fix is to modify the script. Only catch exceptions that you 
can actually handle. Example: a table doesn't exist, and you want to create 
it lazily on first access. Let all other exceptions just bubble up. It may 
seem lazy, but a complete traceback is invaluable for identifying and fixing 
a bug.

(4) self.ERROR.format(e.args[0])

is probably a string with len() > 0, and thus True in a boolean context. 
>From that follows an exception in the find() method in

>                 self.known = self.find()

causes the following if-suite to be run

>                 if self.known:
>                         self.balance = self.get_balance()

and if get_balance() has a same idea of proper exception handling

self.balance will end up containing an error message.

(5) From point (4) I conclude that you don't have unit tests that cover your 
code. You should really write some of these before pondering about stylistic 
issues. Unit tests 

- help avoid errors
- make changes in the code less of a gamble because if the tests succeed 
after the change you can be confident the change didn't introduce an error
- what you might not expect: how drastically tests affect the style of your 
code. You'll see yourself thinking "How can I test that?" with every line of 
code that you write, and that alone will improve the quality of your code.

A simple example is your self.find(). How would you test that with different 
phone numbers? That's easier when you can pass the phone number as an 
argument, so you might change the method's signature.




From duxbuz at hotmail.com  Wed Apr 29 11:44:28 2015
From: duxbuz at hotmail.com (Ian D)
Date: Wed, 29 Apr 2015 09:44:28 +0000
Subject: [Tutor] comparison on Types
Message-ID: <DUB123-W3348BB901D1371C21425D8CBD70@phx.gbl>

I was looking at the example code below. I am using python 2.7.

I am wondering why when I substitute the while n! = "guess" to while n!= guess (<-- no quotes) I get a problem?

The Type string is used for the first conditional comparison in the outer While loop, but afterwards the Type is an int.

I would have expected the guess variable to be used as Type int as it seems to be cast in the raw_input statement and would be comparable to another int that's stored in variable n. Thanks


import random
n = random.randint(1, 99)
guess = int(raw_input("Enter an integer from 1 to 99: "))
while n != "guess":
    print
    if guess < n:
        print "guess is low"
        guess = int(raw_input("Enter an integer from 1 to 99: "))
    elif guess> n:
        print "guess is high"
        guess = int(raw_input("Enter an integer from 1 to 99: "))
    else:
        print "you guessed it!"
        break
    print  		 	   		  

From __peter__ at web.de  Wed Apr 29 12:51:54 2015
From: __peter__ at web.de (Peter Otten)
Date: Wed, 29 Apr 2015 12:51:54 +0200
Subject: [Tutor] comparison on Types
References: <DUB123-W3348BB901D1371C21425D8CBD70@phx.gbl>
Message-ID: <mhqd4b$v6t$1@ger.gmane.org>

Ian D wrote:

> I was looking at the example code below. I am using python 2.7.
> 
> I am wondering why when I substitute the while n! = "guess" to while n!=
> guess (<-- no quotes) I get a problem?

What is that problem? The only thing I see is that the

>     else:
>         print "you guessed it!"
>         break

branch is never executed. You remove it and instead put the 

>         print "you guessed it!"

statement after the loop.
 
> The Type string is used for the first conditional comparison in the outer
> While loop, but afterwards the Type is an int.

Not even that. The guess name is bound to an integer before the loop is 
entered:

> guess = int(raw_input("Enter an integer from 1 to 99: "))
  while n != guess:
     ...

> I would have expected the guess variable to be used as Type int as it
> seems to be cast in the raw_input statement and would be comparable to
> another int that's stored in variable n. Thanks

You have that right.

> import random
> n = random.randint(1, 99)
> guess = int(raw_input("Enter an integer from 1 to 99: "))
> while n != "guess":
>     print
>     if guess < n:
>         print "guess is low"
>         guess = int(raw_input("Enter an integer from 1 to 99: "))
>     elif guess> n:
>         print "guess is high"
>         guess = int(raw_input("Enter an integer from 1 to 99: "))
>     else:
>         print "you guessed it!"
>         break
>     print



From steve at pearwood.info  Wed Apr 29 13:14:06 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 29 Apr 2015 21:14:06 +1000
Subject: [Tutor] comparison on Types
In-Reply-To: <DUB123-W3348BB901D1371C21425D8CBD70@phx.gbl>
References: <DUB123-W3348BB901D1371C21425D8CBD70@phx.gbl>
Message-ID: <20150429111404.GZ5663@ando.pearwood.info>

On Wed, Apr 29, 2015 at 09:44:28AM +0000, Ian D wrote:

> I was looking at the example code below. I am using python 2.7.
> 
> I am wondering why when I substitute the while n! = "guess" to while 
> n!= guess (<-- no quotes) I get a problem?

Really? What sort of problem? It looks okay to me, although I haven't 
run it.


> The Type string is used for the first conditional comparison in the 
> outer While loop, but afterwards the Type is an int.
> 
> I would have expected the guess variable to be used as Type int as it 
> seems to be cast in the raw_input statement and would be comparable to 
> another int that's stored in variable n. Thanks

I'm having difficulty understanding your question. It might help if you 
explain what you think the code should do, versus what it actually does. 
Do you get an error? Then post the full error traceback, starting from 
the line "Traceback" to the end.

It also might help to understand that in Python, *variables* don't have 
types, but values do. Variables can take any value, and take on the type 
of that value until such time as they change to a different value:

py> x = "Hello"
py> type(x)
<type 'str'>
py> x = 23
py> type(x)
<type 'int'>




Looking at your code, I can see only one obvious (to me) problem:

> import random
> n = random.randint(1, 99)
> guess = int(raw_input("Enter an integer from 1 to 99: "))
> while n != "guess":

By using the string "guess", you guarantee that n is *never* equal on 
the first test. That means that the loop will be entered. If you remove 
the quotation marks, and compare n != guess (here guess is the variable, 
not the literal string) then if your guess happens to be correct on the 
first time, the while loop will not be entered and the program will just 
end.

     print
>     if guess < n:
>         print "guess is low"
>         guess = int(raw_input("Enter an integer from 1 to 99: "))
>     elif guess> n:
>         print "guess is high"
>         guess = int(raw_input("Enter an integer from 1 to 99: "))
>     else:
>         print "you guessed it!"
>         break
>     print  		 	   		  


Try this instead:


import random
n = random.randint(1, 99)
guess = 0  # Guaranteed to not equal n.
while n != guess:
    guess = int(raw_input("Enter an integer from 1 to 99: "))
    print
    if guess < n:
        print "guess is too low"
    elif guess > n:
        print "guess is too high"
    else:
        print "guessed correctly!"




Does that help?



-- 
Steve

From steve at pearwood.info  Wed Apr 29 13:27:21 2015
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 29 Apr 2015 21:27:21 +1000
Subject: [Tutor] if then statements
In-Reply-To: <930077296.270499.1430270697882.JavaMail.zimbra@stedwards.edu>
References: <187312571.270100.1430270451101.JavaMail.zimbra@stedwards.edu>
 <930077296.270499.1430270697882.JavaMail.zimbra@stedwards.edu>
Message-ID: <20150429112721.GA5663@ando.pearwood.info>

On Tue, Apr 28, 2015 at 08:24:57PM -0500, Jacqueline G Solis wrote:
> hello,
> 
> I keep getting a syntax error. Could you please explain why that 
> happens and how to correct it.

Syntax errors are sometimes a bit tricky. Usually, they tell you were 
the error is:


py> if (x + 1:
  File "<stdin>", line 1
    if (x + 1:
             ^
SyntaxError: invalid syntax


Notice the blank line immediately before "SyntaxError"? If you look 
carefully, you will see a caret ^ which points to the ":" colon in the 
line before. (In your email, it may not quite line up correctly, but in 
the Python interpreter and the console, they should like up.) That 
should make it obvious that I am missing a closing parenthesis before 
the colon.

But sometimes Python doesn't notice the syntax error until the line 
*after* the actual problem:


py> x = (y + 1
... if x:
  File "<stdin>", line 2
    if x:
        ^
SyntaxError: invalid syntax


The actual problem is that I am missing a round bracket in the previous 
line, but Python doesn't realise it until it gets to the colon.

Does that help?


-- 
Steve

From davea at davea.name  Wed Apr 29 14:05:47 2015
From: davea at davea.name (Dave Angel)
Date: Wed, 29 Apr 2015 08:05:47 -0400
Subject: [Tutor] if then statements
In-Reply-To: <930077296.270499.1430270697882.JavaMail.zimbra@stedwards.edu>
References: <930077296.270499.1430270697882.JavaMail.zimbra@stedwards.edu>
Message-ID: <5540C91B.1080505@davea.name>

On 04/28/2015 09:24 PM, Jacqueline G Solis wrote:
> hello,
>
> I keep getting a syntax error. Could you please explain why that happens and how to correct it.
>
>
> def main ():
>      print( "Welcome to Gonzo Burger!")
>      order= int(input("Enter 1 if you want a hamburger,\
>      or 2 if you want a cheeseburger:" ))
>      if order == 1 :
>                 print("order: 1")
>      else:
>                 print("Order: 2")
>
>      drink=int(input("Thank you! Next, enter a 1 if you want a Coke,\
>      or a 2 if you want a Sprite:")
>      if drink == 1 :

The line before this one has a missing right paren at the end.  you 
close the input() function, but not the int() function.  So the next 
thing would have to be a comma, not a reserved token "if"

>                print("Order: 1")
>      else:
>                print("Order: 2")
>
>      print("Thank you! You ordered:")
>      if order == 1:
>                print("- Hamburger")
>      else:
>                print("- Cheeseburger")
>      if drink == 1 :
>                print("- Coke")
>      else:
>                print("- Sprite")
>
> main ()
>
>
>
>
> -Jackie
> p.s: the error happens in the second if statement.

That's a good hint.  Better would be to include the full traceback with 
the error message, instead of a one-word summary.  No matter in this 
caswe, but it's a good habit to get into.

Incidentally, for syntax errors, it's pretty common for the real problem 
to be in the line before, or even earlier.  I'd assume this error 
pointed at the 'if'.  So you're really only going back one token.




-- 
DaveA

From duxbuz at hotmail.com  Wed Apr 29 14:23:20 2015
From: duxbuz at hotmail.com (Ian D)
Date: Wed, 29 Apr 2015 12:23:20 +0000
Subject: [Tutor] comparison on Types
In-Reply-To: <20150429111404.GZ5663@ando.pearwood.info>
References: <DUB123-W3348BB901D1371C21425D8CBD70@phx.gbl>,
 <20150429111404.GZ5663@ando.pearwood.info>
Message-ID: <DUB123-W11324EEDA0DE31DD75BA78CBD70@phx.gbl>

Ok thanks. I thought it would be better with just a while True loop; for simple clarity.

----------------------------------------
> Date: Wed, 29 Apr 2015 21:14:06 +1000
> From: steve at pearwood.info
> To: tutor at python.org
> Subject: Re: [Tutor] comparison on Types
>
> On Wed, Apr 29, 2015 at 09:44:28AM +0000, Ian D wrote:
>
>> I was looking at the example code below. I am using python 2.7.
>>
>> I am wondering why when I substitute the while n! = "guess" to while
>> n!= guess (<-- no quotes) I get a problem?
>
> Really? What sort of problem? It looks okay to me, although I haven't
> run it.
>
>
>> The Type string is used for the first conditional comparison in the
>> outer While loop, but afterwards the Type is an int.
>>
>> I would have expected the guess variable to be used as Type int as it
>> seems to be cast in the raw_input statement and would be comparable to
>> another int that's stored in variable n. Thanks
>
> I'm having difficulty understanding your question. It might help if you
> explain what you think the code should do, versus what it actually does.
> Do you get an error? Then post the full error traceback, starting from
> the line "Traceback" to the end.
>
> It also might help to understand that in Python, *variables* don't have
> types, but values do. Variables can take any value, and take on the type
> of that value until such time as they change to a different value:
>
> py> x = "Hello"
> py> type(x)
> <type 'str'>
> py> x = 23
> py> type(x)
> <type 'int'>
>
>
>
>
> Looking at your code, I can see only one obvious (to me) problem:
>
>> import random
>> n = random.randint(1, 99)
>> guess = int(raw_input("Enter an integer from 1 to 99: "))
>> while n != "guess":
>
> By using the string "guess", you guarantee that n is *never* equal on
> the first test. That means that the loop will be entered. If you remove
> the quotation marks, and compare n != guess (here guess is the variable,
> not the literal string) then if your guess happens to be correct on the
> first time, the while loop will not be entered and the program will just
> end.
>
> print
>> if guess < n:
>> print "guess is low"
>> guess = int(raw_input("Enter an integer from 1 to 99: "))
>> elif guess> n:
>> print "guess is high"
>> guess = int(raw_input("Enter an integer from 1 to 99: "))
>> else:
>> print "you guessed it!"
>> break
>> print
>
>
> Try this instead:
>
>
> import random
> n = random.randint(1, 99)
> guess = 0 # Guaranteed to not equal n.
> while n != guess:
> guess = int(raw_input("Enter an integer from 1 to 99: "))
> print
> if guess < n:
> print "guess is too low"
> elif guess> n:
> print "guess is too high"
> else:
> print "guessed correctly!"
>
>
>
>
> Does that help?
>
>
>
> --
> Steve
> _______________________________________________
> Tutor maillist - Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor 		 	   		  

From davea at davea.name  Wed Apr 29 14:32:29 2015
From: davea at davea.name (Dave Angel)
Date: Wed, 29 Apr 2015 08:32:29 -0400
Subject: [Tutor] circular movement in pygame
In-Reply-To: <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>	<CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>	<CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>	<CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>	<554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
Message-ID: <5540CF5D.4050105@davea.name>

On 04/29/2015 03:15 AM, diliup gabadamudalige wrote:
> Thanks all for the responses.
> Charles Coss? -  yes I can write a simple pygame program that makes a
> sprite move in a circle but it may not be the style and order that many may
> approve or accept. I consider myself a student. :)
> No one has pointed out why the object moves in a circle properly in the bit
> of code where it is addressed directly and why it does not when the same
> code is applied thru a class.
> I know that an object can be made to move around the circumference of a
> circle by constantly calculating the point and giving the x and y values
>
> 1. x = some code
>
> That is what I used and it worked. I was trying to find how we can do the
> same thing by updating the current position by doing
>
> 2. x += some code

2.  x +=  some different code

>   Above 1 works. 2 does not. Why is that?

Because there is always some little error in the value you're adding to 
x, since it's a floating point value calculated using transcendentals. 
If you're going to loop thousands of times, those little errors add up.

Sometime try measuring a mile using two 12-inch rulers, placing each one 
before picking up the previous. By the time you're done, you'll probably 
be off a hundred feet.


>
> Both the same code.

Not at all the same.

> The same variable is used with different names cause
> some others were confused when they were the same.
>
>   I hope this time I have answered correctly. No more attachments. (e mail
> or otherwise. :) )
>

I can't necessarily understand the code since you use pygame and I'm not 
familiar with pygame.  In your itertools loop, you always reset the 
angle back to 100 degrees.

In your while loop, you issue a call to draw.circle().  Perhaps that's 
the working code you're talking about.



-- 
DaveA

From fomcl at yahoo.com  Wed Apr 29 14:47:18 2015
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Wed, 29 Apr 2015 05:47:18 -0700
Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths
Message-ID: <1430311638.32035.YahooMailBasic@web163802.mail.gq1.yahoo.com>

Hello,

Windows has the 'feature' that the CD command does not work with UNC paths.
So in the code below, I cannot use the 'cwd' parameter of subprocess.Popen.
Therefore I use pushd/popd to accomplish the same effect. Is there a better way to do this?
(other than using full path names everywhere, or os.chdir). Would it be a useful improvement
of Python itself if cwd also works with UNC path? 

import sys
import os
import getpass
import subprocess

path = r'\\server\share\possibly with\space'
executable = 'blah.exe'
username = os.getenv("USERNAME")
password = getpass.getpass("Enter password: ")
infile =  sys.argv[1]
outfile = sys.argv[2]
cmds = ['pushd "%s" &&' % path, executable, username, password, infile, outfile, "&& popd"]

result = subprocess.Popen(" ".join(cmds), shell=True)
error = result.stderr
if error:
    raise RuntimeError(error.read())

Regards,

Albert-Jan

PS: Python 2.7 on Windows 7 32



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a 

fresh water system, and public health, what have the Romans ever done for us?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

From davea at davea.name  Wed Apr 29 16:02:12 2015
From: davea at davea.name (Dave Angel)
Date: Wed, 29 Apr 2015 10:02:12 -0400
Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths
In-Reply-To: <1430311638.32035.YahooMailBasic@web163802.mail.gq1.yahoo.com>
References: <1430311638.32035.YahooMailBasic@web163802.mail.gq1.yahoo.com>
Message-ID: <5540E464.5090003@davea.name>

On 04/29/2015 08:47 AM, Albert-Jan Roskam wrote:
> Hello,
>
> Windows has the 'feature' that the CD command does not work with UNC paths.
> So in the code below, I cannot use the 'cwd' parameter of subprocess.Popen.
> Therefore I use pushd/popd to accomplish the same effect. Is there a better way to do this?
> (other than using full path names everywhere, or os.chdir). Would it be a useful improvement
> of Python itself if cwd also works with UNC path?
>
> import sys
> import os
> import getpass
> import subprocess
>
> path = r'\\server\share\possibly with\space'
> executable = 'blah.exe'
> username = os.getenv("USERNAME")
> password = getpass.getpass("Enter password: ")
> infile =  sys.argv[1]
> outfile = sys.argv[2]
> cmds = ['pushd "%s" &&' % path, executable, username, password, infile, outfile, "&& popd"]
>
> result = subprocess.Popen(" ".join(cmds), shell=True)
> error = result.stderr
> if error:
>      raise RuntimeError(error.read())
>
> Regards,
>
> Albert-Jan
>
> PS: Python 2.7 on Windows 7 32
>

Just a comment about Windows.  There is a current directory for each 
lettered drive partition.  But a unc name is not necessarily on any 
known drive.

And if executable, infile and outfile might have spaces within them, you 
need to quote them as well.




-- 
DaveA

From __peter__ at web.de  Wed Apr 29 16:11:38 2015
From: __peter__ at web.de (Peter Otten)
Date: Wed, 29 Apr 2015 16:11:38 +0200
Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths
References: <1430311638.32035.YahooMailBasic@web163802.mail.gq1.yahoo.com>
Message-ID: <mhqoqs$g7g$1@ger.gmane.org>

Albert-Jan Roskam wrote:

> Hello,
> 
> Windows has the 'feature' that the CD command does not work with UNC
> paths. So in the code below, I cannot use the 'cwd' parameter of
> subprocess.Popen. Therefore I use pushd/popd to accomplish the same
> effect. Is there a better way to do this? (other than using full path
> names everywhere, or os.chdir). Would it be a useful improvement of Python
> itself if cwd also works with UNC path?

What is the error you get? I don't have Windows to verify, but a quick look 
into the subprocess source suggests that it uses CreateProcess().
Googling for that finds

<https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx>

which states

"""
lpCurrentDirectory [in, optional]
The full path to the current directory for the process. The string can also 
specify a UNC path.
"""

> import sys
> import os
> import getpass
> import subprocess
> 
> path = r'\\server\share\possibly with\space'
> executable = 'blah.exe'
> username = os.getenv("USERNAME")
> password = getpass.getpass("Enter password: ")
> infile =  sys.argv[1]
> outfile = sys.argv[2]
> cmds = ['pushd "%s" &&' % path, executable, username, password, infile,
> outfile, "&& popd"]
> 
> result = subprocess.Popen(" ".join(cmds), shell=True)
> error = result.stderr
> if error:
>     raise RuntimeError(error.read())
> 
> Regards,
> 
> Albert-Jan
> 
> PS: Python 2.7 on Windows 7 32
> 
> 
> 
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> All right, but apart from the sanitation, the medicine, education, wine,
> public order, irrigation, roads, a
> 
> fresh water system, and public health, what have the Romans ever done for
> us?
> 
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



From robertvstepp at gmail.com  Wed Apr 29 16:21:39 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 29 Apr 2015 09:21:39 -0500
Subject: [Tutor] How to use Git from Windows PC for files on Solaris machine
 where Git cannot be installed?
Message-ID: <CANDiX9+gFB_jVUm7DUFV74+j0E9pxPWSCAfTUcZ5M1no_2tqcA@mail.gmail.com>

I now have Git installed on my Windows 7 PC at work. The files that I
wish to put under Git version control exist on a Solaris 10
workstation. In the Git bash provided, I can ssh into the Solaris 10
machine. I also can the CuteFTP program on my Windows PC to
move/copy/etc. files between the two machines. How can I put these
Solaris files under version control under these circumstances? I
thought I had conceptually seen how to accomplish this via ssh, but if
it is doable, my limited knowledge of Git and ssh is insufficient to
find the path of success.

In order to at least start putting these files under version control,
I have created a repository for these files on an intranet drive, used
CuteFTP to copy them into the repository from Solaris, and cloned this
repository to my Windows PC. My current workflow is very clunky
indeed: 1) Bring up file(s) to edit in my Windows editor from my local
project working directory. 2) Perform edits. 3) Save edits. 4) In Git
bash stage these. 5) Either CuteFTP or scp from Git bash the changed
files to Solaris. 6) Test files in Solaris. 7) Repeat. As needed do
Git commits and pushes.

This is better than what I had been doing. At least I *am* moving into
the version control world. But how can I make this (hopefully, lots)
better?

BTW, I have Git working well at home. As an update I am working on
learning how to use Python's unittest module at home. Once I am
successful there, I will implement this at work: after the fact on
existing projects and from the get-go on new ones.

-- 
boB

From cybervigilante at gmail.com  Wed Apr 29 17:34:17 2015
From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP)
Date: Wed, 29 Apr 2015 08:34:17 -0700
Subject: [Tutor] Fwd:  Function works one time then subsequently fails
In-Reply-To: <CALRAYNXaHHNLFPt75ywqmPaEEjhLCAtbctM+-cQ19bQ3zz5OoQ@mail.gmail.com>
References: <CALRAYNWD5UPjPxVEyUy-ErgEQTo0HsL6Kz47jZ3uErjD-eiLbA@mail.gmail.com>
 <20150429054003.GA43610@cskk.homeip.net>
 <CALRAYNXaHHNLFPt75ywqmPaEEjhLCAtbctM+-cQ19bQ3zz5OoQ@mail.gmail.com>
Message-ID: <CALRAYNXBKSp-JoSHzKx2ONn3YZHuG8nJLGGPEDs9AgVSCyBNDQ@mail.gmail.com>

On 28 April 2015 at 22:40, Cameron Simpson <cs at zip.com.au> wrote:

>
> As with all things, sometimes that cannot be reasonably achieved, but it
> is usually so.
>
> We can pick over your code as well if you like. Should we?
>
> Cheers,
> Cameron Simpson <cs at zip.com.au>


Sure, but let me include the full working program after fixup. Although I
still have to write another program to feed it random problems to work it
out. It's a bit spacey, but I ran it through the pep8 program and it
suggested that. I think two spaces between such tiny functions is overkill,
though.

"""
Takes the name of a binary math operation and two numbers from input,
repeatedly, and displays the results until done
"""

def add(a, b):
    return a + b


def subtract(a, b):
    return b - a


def minus(a, b):
    return a - b


def multiply(a, b):
    return a * b


def divide(a, b):
    return a / b


operations = {'add': add, '+': add, 'plus': add, 'subtract': subtract,
'subtracted': subtract,
              '-': minus, 'minus': minus, 'multiply': multiply, '*':
multiply, 'multiplied': multiply,
              'times': multiply, 'divide': divide, '/': divide, 'divided':
divide}

def test_number(astring):
    """
    Input: A string that should represent a valid int or float. Output:
    An int or float on success. None on failure.
    """
    for make_type in (int, float):
        try:
            return make_type(astring)
        except ValueError:
            pass
    return None


def parse_string(math_string):
    """Input: A math string with a verbal or mathematical operation
    and two valid numbers to operate on. Extra numbers and operations
    are ignored. Output: A tuple containing a function corresponding
    to the operation and the two numbers. Returns None on failure.
    """
    operation = None
    tokens = math_string.split()
    numbers = []
    for token in tokens:
        if token in operations:
            operation = operations[token]
        elif test_number(token) != None:
            numbers.append(test_number(token))
        if len(numbers) > 1:
            break
    if operation is None or len(numbers) < 2:
        return None
    else:
        return operation, numbers[0], numbers[1]

instructions = '''Enter two numbers and one of the four basid math
operations,
either mathematical or verbal. i.e. 3 + 2, 12 divided by 14, 10 minus 4,
etc.
Enter done to quit.
'''
try:
    user_input = input(instructions)
    while True:
        if user_input == 'done':
            break
        result = parse_string(user_input)
        if result == None:
            print("Not a valid math operation.")
        else:
            func, num1, num2 = result
            print(func(num1, num2))
        user_input = input()
except KeyboardInterrupt:
    print("Program terminated by user")


-- 
Jim

If you only had one hour left to live, would you spend it on Facebook,
Twitter, or Google Plus?

From jugurtha.hadjar at gmail.com  Wed Apr 29 18:03:41 2015
From: jugurtha.hadjar at gmail.com (Jugurtha Hadjar)
Date: Wed, 29 Apr 2015 17:03:41 +0100
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
In-Reply-To: <mhq3dh$lnt$1@ger.gmane.org>
References: <55404A9D.5010103@gmail.com> <mhq3dh$lnt$1@ger.gmane.org>
Message-ID: <554100DD.3080000@gmail.com>

On 04/29/2015 09:06 AM, Alan Gauld wrote:
> In principle its an acceptable strategy. A close alternative
> would be to name the queries as explicit class variables.
> So for example you would use:
>
> cur.execute(self.find_phone_query,(....))
>
> Its less typing and less error prone in that you get a
> syntax error on mistyping rather than a run time exception.
>

That's what I had initially but I used dictionaries for regexes I match 
the messages against to determine the type, I thought I'd organize stuff 
of the same nature together in a dictionary.
	
	JUNK = 'JUNK'

	RE_TYPE = {
		'TYPE1'  : re.compile(r'xxx'),
		'TYPE2'  : re.compile(r'yyy'),
		  ...
		'TYPEn'  : re.compile(r'aaa'),
	}

Then to get the type of the message, I just have to do:

	gen = (k for k in self.RE_TYPE if RE_TYPE[k].findall(msg_text))
	msg_type = next(gen, self.JUNK)


>> - Methods closed the connection themselves, so I used `with` in
>> `init_db` instead of `try`, as it would close the connection
>> automatically and rollback (I hope I'm not making this up).
>
> Try/except and with do different things but in this case
> you can get away with it. The only loss is that your errors
> here are not formatted in the same way as the other messages.

I wrote it to do one specific job that's to be followed by some other 
task that _would_ raise an exception.

Maybe it's lazy and am relying on the methods that call `init_db` to 
deal with the error. `init_db` just returns a connection and a cursor.. 
If the file didn't exist, it'd be created but without schema, the 
calling method (like `create` or `find` _will_, however produce an error 
as it tries to read/write.


> Consider using docstrings rather than comments to describe the method
> I see you do that below...

Roger that.

>>          (__, cursor) = self.init_db()
>
> Don't use the __ 'variable' here, be explicit, it makes
> maintenance much easier.
>

I actually searched specifically for something like this. In MATLAB, 
there's the ~ that does this. I'm not trying to write Python in a MATLAB 
style, but I was glad I found it here:

http://docs.python-guide.org/en/latest/writing/style/#create-an-ignored-variable

I was only interested in the cursor in that method. `init_db` returned 
only a connection in the beginning, but I didn't want to write 
conn.cursor every time.


>>          try:
>>              cursor.execute(
>>                  self.QUERIES['FIND_PHONE'],
>>                  (self.phone,)
>>              )
>>              found = cursor.fetchone()
>>              return True if found else False
>>          except Exception as e:
>>              return self.ERROR.format(e.args[0])
>
> Don't catch Exception, it's too wide. Catch the
> actual errors that might arise, be as specific as possible.

Thanks for bringing that to my attention.

>
>>      def create(self, seed_balance):
>>          ''' Create a database entry for the sender.'''
>>
>>          conn, cursor = self.init_db()
>>          try:
>>              cursor.execute(
>>                  self.QUERIES['CREATE'],
>>                  (self.phone, seed_balance)
>>              )
>>              conn.commit()
>>          except Exception as e:
>>              return self.ERROR.format(e.args[0])
>
>
> as above
>
>

Thank you for the feedback, Alan.


-- 
~Jugurtha Hadjar,

From diliupg at gmail.com  Wed Apr 29 10:03:11 2015
From: diliupg at gmail.com (diliup gabadamudalige)
Date: Wed, 29 Apr 2015 13:33:11 +0530
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <mhq2c2$pr$1@ger.gmane.org>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
 <mhq2c2$pr$1@ger.gmane.org>
Message-ID: <CAMxbqSP51m7O45RwnSM1VY0MnCXH8majshwfC=_md7-YxP07XQ@mail.gmail.com>

Thank you Alan. Understood. I already knew that. My question is

How to to do it the second way.
some code = what?
My question is, how does one arrive at the code to put in place of "some
code"? The code I used does not work correctly.
The code is in this chain of email.
I hope I am clear in what I am trying to do.



On Wed, Apr 29, 2015 at 1:18 PM, Alan Gauld <alan.gauld at btinternet.com>
wrote:

> On 29/04/15 08:15, diliup gabadamudalige wrote:
>
>  1. x = some code
>>
>> That is what I used and it worked. I was trying to find how we can do the
>> same thing by updating the current position by doing
>>
>> 2. x += some code
>>   Above 1 works. 2 does not. Why is that?
>>
>
>
> Because they do completely different things!
>
> 1 is simply
>
> x = some code
>
> 2 is
>
> x = x + some code
>
> In 2 you are adding x to some code.
>
> Of course they don't work the same.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Diliup Gabadamudalige

http://www.diliupg.com
http://soft.diliupg.com/

**********************************************************************************************
This e-mail is confidential. It may also be legally privileged. If you are
not the intended recipient or have received it in error, please delete it
and all copies from your system and notify the sender immediately by return
e-mail. Any unauthorized reading, reproducing, printing or further
dissemination of this e-mail or its contents is strictly prohibited and may
be unlawful. Internet communications cannot be guaranteed to be timely,
secure, error or virus-free. The sender does not accept liability for any
errors or omissions.
**********************************************************************************************

From diliupg at gmail.com  Wed Apr 29 10:13:49 2015
From: diliupg at gmail.com (diliup gabadamudalige)
Date: Wed, 29 Apr 2015 13:43:49 +0530
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
Message-ID: <CAMxbqSN2ZNDK8k7FfkftFyZ8L5TPRTJvvTL0ddZvnQr=D1vNcA@mail.gmail.com>

question to Lucas.

Not sure if this is what you're looking for, but I would also use cos for
the x coordinate as suggested.  If:

self.rect.x = self.radius * math.cos(self.angle) + self.center_x
self.rect.y = self.radius * math.sin(self.angle) + self.center_y

Take a derivative (assume:  angle += angular_vel * dt for every increment
in time dt), so that:

self.rect.x += -self.radius * math.sin(self.angle) * self.angular_vel * dt
self.rect.y += self.radius * math.cos(self.angle) * self.angular_vel * dt

what is dt?


On Wed, Apr 29, 2015 at 12:45 PM, diliup gabadamudalige <diliupg at gmail.com>
wrote:

> Thanks all for the responses.
> Charles Coss? -  yes I can write a simple pygame program that makes a
> sprite move in a circle but it may not be the style and order that many may
> approve or accept. I consider myself a student. :)
> No one has pointed out why the object moves in a circle properly in the
> bit of code where it is addressed directly and why it does not when the
> same code is applied thru a class.
> I know that an object can be made to move around the circumference of a
> circle by constantly calculating the point and giving the x and y values
>
> 1. x = some code
>
> That is what I used and it worked. I was trying to find how we can do the
> same thing by updating the current position by doing
>
> 2. x += some code
>  Above 1 works. 2 does not. Why is that?
>
> Both the same code. The same variable is used with different names cause
> some others were confused when they were the same.
>
>  I hope this time I have answered correctly. No more attachments. (e mail
> or otherwise. :) )
>



-- 
Diliup Gabadamudalige

http://www.diliupg.com
http://soft.diliupg.com/

**********************************************************************************************
This e-mail is confidential. It may also be legally privileged. If you are
not the intended recipient or have received it in error, please delete it
and all copies from your system and notify the sender immediately by return
e-mail. Any unauthorized reading, reproducing, printing or further
dissemination of this e-mail or its contents is strictly prohibited and may
be unlawful. Internet communications cannot be guaranteed to be timely,
secure, error or virus-free. The sender does not accept liability for any
errors or omissions.
**********************************************************************************************

From diliupg at gmail.com  Wed Apr 29 11:15:00 2015
From: diliupg at gmail.com (diliup gabadamudalige)
Date: Wed, 29 Apr 2015 14:45:00 +0530
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <554095BF.2000208@btinternet.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
 <mhq2c2$pr$1@ger.gmane.org>
 <CAMxbqSP51m7O45RwnSM1VY0MnCXH8majshwfC=_md7-YxP07XQ@mail.gmail.com>
 <554095BF.2000208@btinternet.com>
Message-ID: <CAMxbqSOv+jTT0brUL1ny_irBMBsDzASS4cSqrqLtVJcjaUyO8w@mail.gmail.com>

x=42 good
x += 42 -x ?

That does not go by a mile of what I asked.
Alan, are you telling me that there is no way that one can arrive at X2
which is the NEXT place that X1 will be after "some increment"?
old x position = X1

new x position= X1 + some increment value
which can be written as :new X = oldX + some increment value

which can be simplified to X += some increment value?

my orginal question was

*Why does the object NOT move in a circle when implemented as a class?*

All the code was provided.


The above is  what I asked. (I hope this is clear enough)









On Wed, Apr 29, 2015 at 1:56 PM, Alan Gauld <alan.gauld at btinternet.com>
wrote:

> On 29/04/15 09:03, diliup gabadamudalige wrote:
>
>> Thank you Alan. Understood. I already knew that. My question is
>>
>> How to to do it the second way.
>> some code = what?
>>
>>  The point is you cannot do it.
> The second approach always uses the current value of x.
> The first approach may or may not use the current value
> of x. If it does not use x then the += style cannot be
> made to work (unless you tag a -x on at the end!
>
> x = 42
>
> x += 42-x
>
> Which is just stupid.
>
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>


-- 
Diliup Gabadamudalige

http://www.diliupg.com
http://soft.diliupg.com/

**********************************************************************************************
This e-mail is confidential. It may also be legally privileged. If you are
not the intended recipient or have received it in error, please delete it
and all copies from your system and notify the sender immediately by return
e-mail. Any unauthorized reading, reproducing, printing or further
dissemination of this e-mail or its contents is strictly prohibited and may
be unlawful. Internet communications cannot be guaranteed to be timely,
secure, error or virus-free. The sender does not accept liability for any
errors or omissions.
**********************************************************************************************

From alan.gauld at btinternet.com  Wed Apr 29 18:30:33 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Apr 2015 17:30:33 +0100
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSOv+jTT0brUL1ny_irBMBsDzASS4cSqrqLtVJcjaUyO8w@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
 <mhq2c2$pr$1@ger.gmane.org>
 <CAMxbqSP51m7O45RwnSM1VY0MnCXH8majshwfC=_md7-YxP07XQ@mail.gmail.com>
 <554095BF.2000208@btinternet.com>
 <CAMxbqSOv+jTT0brUL1ny_irBMBsDzASS4cSqrqLtVJcjaUyO8w@mail.gmail.com>
Message-ID: <mhr0v6$8cs$1@ger.gmane.org>

On 29/04/15 10:15, diliup gabadamudalige wrote:
> x=42 good
> x += 42 -x ?
>
> That does not go by a mile of what I asked.

You've asked three different things:

1) Why the += form gives different results from the assignment form,
2) Why some code you apparently wriotre worked outside a class
    but not in a class
3) A specific question about some code for moving an object
    in PyGame around in a circle

Number 1 is the only one I can comment on as I can't see your 
attachments. That is what I (and several others) have answered.
They are fundamentally different. There is no general way
to make an augmented assignment such that

x = f(y) and
x += f(y)  (or even g(y))

produce the same result except by the trivial

x += g(y) - x

> Alan, are you telling me that there is no way that one can arrive at X2
> which is the NEXT place that X1 will be after "some increment"?
> old x position = X1

No, that is a completely separate question and has nothing
to do with using augmented assignment. But it does depend
on the specifics of the situation and is mainly a mathematical
problem rather than a Python one..

> new x position= X1 + some increment value
> which can be written as :new X = oldX + some increment value
>
> which can be simplified to X += some increment value?

That may or may not be possible, it depends on what the
original equation in the pure assignment model is.

> my orginal question was
>
> *Why does the object NOT move in a circle when implemented as a class?*

Your original question was:

is there a way to do
self.rect.x +*= some value*
self.rect.y += some value

rather than

self.rect.x = self.radius * math.sin(self.angle) + self.center_x
self.rect.y = self.radius * math.cos(self.angle) + self.center_y

Which is about the use of augmented assignment.

> All the code was provided.

No it wasn't. I have not seen any of your code because you persist
in sending it as attachments which (as you've been told) do not
work reliably in a text based mailing list. If you want
comments on the code either post it inline in your message
or as a link to a web site where we can all see it.

> The above is  what I asked. (I hope this is clear enough)

Your class based code should work but without sight of it
I cannot begin to guess about that aspect of your problem.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Wed Apr 29 18:43:19 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Apr 2015 17:43:19 +0100
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
In-Reply-To: <554100DD.3080000@gmail.com>
References: <55404A9D.5010103@gmail.com> <mhq3dh$lnt$1@ger.gmane.org>
 <554100DD.3080000@gmail.com>
Message-ID: <mhr1n5$lj7$1@ger.gmane.org>

On 29/04/15 17:03, Jugurtha Hadjar wrote:

>>>          (__, cursor) = self.init_db()
>>
>> Don't use the __ 'variable' here, be explicit, it makes
>> maintenance much easier.
>>
>
> I actually searched specifically for something like this. In MATLAB,
> there's the ~ that does this. I'm not trying to write Python in a MATLAB
> style, but I was glad I found it here:
>
> http://docs.python-guide.org/en/latest/writing/style/#create-an-ignored-variable

I've seen this before and strongly disagree with it.
I suspect the author has never had to run a major
maintenance project!

A single underscore is, I agree, far worse that a dunder symbol
but both are a maintenance nightmare. They are ambiguous,
difficult to remember, easy to overlook and if you change
your mind and decide you need to use it later it's a whole
new name to go back and introduce (or worse be tempted to use the 
meaningless symbol). And if you need another 'throw-away' name
later you use the same one, then forget there are two uses
and try to use it anyway (even in debugging) and get
completely wrong values, that may or may not look different
to what you expect. (looking different is good - you can
detect it easily, looking similar is very, very, bad!)...
its just a horror story waiting to trip you up.

It's far better to have a short meaningful name that is never
used than a bland, meaningless, generic symbol.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From fomcl at yahoo.com  Wed Apr 29 18:54:11 2015
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Wed, 29 Apr 2015 09:54:11 -0700
Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths
Message-ID: <1430326451.93582.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>


-----------------------------
On Wed, Apr 29, 2015 4:11 PM CEST Peter Otten wrote:

>Albert-Jan Roskam wrote:
>
>> Hello,
>> 
>> Windows has the 'feature' that the CD command does not work with UNC
>> paths. So in the code below, I cannot use the 'cwd' parameter of
>> subprocess.Popen. Therefore I use pushd/popd to accomplish the same
>> effect. Is there a better way to do this? (other than using full path
>> names everywhere, or os.chdir). Would it be a useful improvement of Python
>> itself if cwd also works with UNC path?
>
>What is the error you get? I don't have Windows to verify, but a quick look 
>into the subprocess source suggests that it uses CreateProcess().
>Googling for that finds
>
><https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx>
>
>which states
>
>""
>lpCurrentDirectory [in, optional]
>The full path to the current directory for the process. The string can also 
>specify a UNC path.
>""

Hmmm, that sounds pretty convincing indeed (makes it even stranger that CD works the way it works). I believe it threw a WindowsError, indicating that the file(s) could not be found, because the dir was not changed. I actually first ran into this problem with this script, so with my current script I immediately refrained from using cwd: http://code.activestate.com/recipes/578883-git-pre-commit-hook-to-reject-large-files-using-py/
Git gave a fatal error in windows and the pushd/popd fixed it.

>> import sys
>> import os
>> import getpass
>> import subprocess
>> 
>> path = r'\\server\share\possibly with\space'
>> executable = 'blah.exe'
>> username = os.getenv("USERNAME")
>> password = getpass.getpass("Enter password: ")
>> infile =  sys.argv[1]
>> outfile = sys.argv[2]
>> cmds = ['pushd "%s" &&' % path, executable, username, password, infile,
>> outfile, "&& popd"]
>> 
>> result = subprocess.Popen(" ".join(cmds), shell=True)
>> error = result.stderr
>> if error:
>>     raise RuntimeError(error.read())
>> 
>> Regards,
>> 
>> Albert-Jan
>> 
>> PS: Python 2.7 on Windows 7 32


From fomcl at yahoo.com  Wed Apr 29 19:04:41 2015
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Wed, 29 Apr 2015 10:04:41 -0700
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
	machine where Git cannot be installed?
Message-ID: <1430327081.72982.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>


------------------------------
On Wed, Apr 29, 2015 4:21 PM CEST boB Stepp wrote:

>I now have Git installed on my Windows 7 PC at work. The files that I
>wish to put under Git version control exist on a Solaris 10
>workstation. In the Git bash provided, I can ssh into the Solaris 10
>machine. I also can the CuteFTP program on my Windows PC to
>move/copy/etc. files between the two machines. How can I put these
>Solaris files under version control under these circumstances? I
>thought I had conceptually seen how to accomplish this via ssh, but if
>it is doable, my limited knowledge of Git and ssh is insufficient to
>find the path of success.


Uhmm, I'd (1) open a Github or Bitbucket account (2) ssh to the solaris machine (3) install git if needed (4) clone your repo (which has just the readme file at this point) (5) fill the local files, git add what you want to track, the git commit and git push. (6) in windows you can use msysgit to connect to your remote repo.

But uhhm, this is not Python at all ;-)

Albert-Jan

From robertvstepp at gmail.com  Wed Apr 29 19:12:43 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 29 Apr 2015 12:12:43 -0500
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
 machine where Git cannot be installed?
In-Reply-To: <1430327081.72982.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
References: <1430327081.72982.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
Message-ID: <CANDiX9+K0fn1FEepYLJey8bw8OGhK6ABToafftNzqoE05ekSQQ@mail.gmail.com>

On Wed, Apr 29, 2015 at 12:04 PM, Albert-Jan Roskam <fomcl at yahoo.com> wrote:
>
> ------------------------------
> On Wed, Apr 29, 2015 4:21 PM CEST boB Stepp wrote:
>
>>I now have Git installed on my Windows 7 PC at work. The files that I
>>wish to put under Git version control exist on a Solaris 10
>>workstation. In the Git bash provided, I can ssh into the Solaris 10
>>machine. I also can the CuteFTP program on my Windows PC to
>>move/copy/etc. files between the two machines. How can I put these
>>Solaris files under version control under these circumstances? I
>>thought I had conceptually seen how to accomplish this via ssh, but if
>>it is doable, my limited knowledge of Git and ssh is insufficient to
>>find the path of success.
>
>
> ... (3) install git if needed ...

It seems Git is needed, but I am not allowed to install it on the
Solaris workstation. So is there a way around this?

>
> But uhhm, this is not Python at all ;-)

I was hoping for clemency on this point due to the earlier thread(s) I
started (Which included Python's unittest module.).



-- 
boB

From alan.gauld at btinternet.com  Wed Apr 29 19:38:35 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Apr 2015 18:38:35 +0100
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
 machine where Git cannot be installed?
In-Reply-To: <CANDiX9+K0fn1FEepYLJey8bw8OGhK6ABToafftNzqoE05ekSQQ@mail.gmail.com>
References: <1430327081.72982.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
 <CANDiX9+K0fn1FEepYLJey8bw8OGhK6ABToafftNzqoE05ekSQQ@mail.gmail.com>
Message-ID: <mhr4up$fcl$1@ger.gmane.org>

On 29/04/15 18:12, boB Stepp wrote:

>> But uhhm, this is not Python at all ;-)
>
> I was hoping for clemency on this point due to the earlier thread(s) I
> started (Which included Python's unittest module.).

I've been blurring the lines on this one because version control
is something everyone should do whether using Python or not and
as a "beginners" list it seems fair to cover generic VC principles
even in a specific thread on Git.

But to be fair your specific set up is very unusual and it might
be better to take it to a git specific forum for detailed
resolution.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From lac at openend.se  Wed Apr 29 19:52:33 2015
From: lac at openend.se (Laura Creighton)
Date: Wed, 29 Apr 2015 19:52:33 +0200
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
	machine where Git cannot be installed?
In-Reply-To: Message from boB Stepp <robertvstepp@gmail.com> of "Wed,
 29 Apr 2015 09:21:39 -0500."
 <CANDiX9+gFB_jVUm7DUFV74+j0E9pxPWSCAfTUcZ5M1no_2tqcA@mail.gmail.com>
References: <CANDiX9+gFB_jVUm7DUFV74+j0E9pxPWSCAfTUcZ5M1no_2tqcA@mail.gmail.com>
Message-ID: <201504291752.t3THqX5d018344@fido.openend.se>

Glad things are going better.
Next step.  Can you get git running on your solaris machines?  Easiest is
if it is already installed .... or if the powers that be will install it
for you.

But if not, you ought to be able to build your own git from source
and run it on your Solaris machines.

This link

http://joemaller.com/908/how-to-install-git-on-a-shared-host/

is a discription of how somebody did it for Fedora linux.  However, if
you run into trouble trying to do this, you need to talk to somebody
who knows how gcc works on solaris, and where all the dependencies
are, and what whatever error messages you are getting mean.  Ideally
you would have somebody who knows about git, too.  That person
isn't me.  And I don't think that the python-tutor mailing list is the
optimal place to look for such a person.  I'd try some solaris list.
Make sure that whoever you talk to knows that you don't have root access
which is why you are building git from source in the first place, and
gets a copy of exactly what you typed when you tried to build it, and
exactly what you got back in terms of error messages, and output, pasted
in, and not a summary of what you think that those error messages meant.

Best of luck,
Laura


From fomcl at yahoo.com  Wed Apr 29 21:24:37 2015
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Wed, 29 Apr 2015 19:24:37 +0000 (UTC)
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
 machine where Git cannot be installed?
In-Reply-To: <CANDiX9+K0fn1FEepYLJey8bw8OGhK6ABToafftNzqoE05ekSQQ@mail.gmail.com>
References: <CANDiX9+K0fn1FEepYLJey8bw8OGhK6ABToafftNzqoE05ekSQQ@mail.gmail.com>
Message-ID: <1398598326.361255.1430335477832.JavaMail.yahoo@mail.yahoo.com>



----- Original Message -----

> From: boB Stepp <robertvstepp at gmail.com>
> To: tutor <tutor at python.org>
> Cc: 
> Sent: Wednesday, April 29, 2015 7:12 PM
> Subject: Re: [Tutor] How to use Git from Windows PC for files on Solaris machine where Git cannot be installed?
> 
> On Wed, Apr 29, 2015 at 12:04 PM, Albert-Jan Roskam <fomcl at yahoo.com> 
> wrote:
>> 
>>  ------------------------------
>>  On Wed, Apr 29, 2015 4:21 PM CEST boB Stepp wrote:
>> 
>>> I now have Git installed on my Windows 7 PC at work. The files that I
>>> wish to put under Git version control exist on a Solaris 10
>>> workstation. In the Git bash provided, I can ssh into the Solaris 10
>>> machine. I also can the CuteFTP program on my Windows PC to
>>> move/copy/etc. files between the two machines. How can I put these
>>> Solaris files under version control under these circumstances? I
>>> thought I had conceptually seen how to accomplish this via ssh, but if
>>> it is doable, my limited knowledge of Git and ssh is insufficient to
>>> find the path of success.
>> 
>> 
>>  ... (3) install git if needed ...
> 
> It seems Git is needed, but I am not allowed to install it on the
> Solaris workstation. So is there a way around this?


Ouch, that sucks. When I said "if needed", I meant "if not already there". Maybe somebody knows a smart solution with rsync or with ftp. Still, then you'd run your tests on Windows, but the code is for Solaris.

 >>  But uhhm, this is not Python at all ;-)
> 
> I was hoping for clemency on this point due to the earlier thread(s) I
> started (Which included Python's unittest module.).


I *love* Git (well, that sounds *very* geeky!) so I don't mind at all.
Once you've got it running, you could install a commit hook that runs nosetests (or even tox).
That's just two lines (a shebang and a call to once of those scripts) and then your unittests will be run automatically every time you do a git commit. Nice! 

From diliupg at gmail.com  Wed Apr 29 20:37:05 2015
From: diliupg at gmail.com (diliup gabadamudalige)
Date: Thu, 30 Apr 2015 00:07:05 +0530
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <mhr0v6$8cs$1@ger.gmane.org>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
 <mhq2c2$pr$1@ger.gmane.org>
 <CAMxbqSP51m7O45RwnSM1VY0MnCXH8majshwfC=_md7-YxP07XQ@mail.gmail.com>
 <554095BF.2000208@btinternet.com>
 <CAMxbqSOv+jTT0brUL1ny_irBMBsDzASS4cSqrqLtVJcjaUyO8w@mail.gmail.com>
 <mhr0v6$8cs$1@ger.gmane.org>
Message-ID: <CAMxbqSM9R=-wXb-Ah6fErw0Z_tQTO0RxBGSUzd8tY0mz93yOgA@mail.gmail.com>

I do not understand how Alan does not get the code that is in this thread.
Anyway I can conclude by saying that a friend of mine who is not in this
thread solved the problem and I would like to share it with you. He has
changed only a very smal portion in the original code that i posted in this
thread. and it works perfectly. Apparently the problem is in the way the
rect assignment is done in the Python/Pygame rect class. So as conclusion
the code below works perfectly. No drifting. Class implemented. I hope
everyone gets updated. Thanks for your time.


import sys, os, pygame, itertools
from math import sin,cos,pi
from pygame.locals import *
SCREENW = 800
SCREENH = 700
class object_factory(pygame.sprite.Sprite):
    def __init__(self, image, xpos = 0, ypos = 0):
        """Constructor"""
        pygame.sprite.Sprite.__init__(self)
        self.image = image
        self.mask = pygame.mask.from_surface(self.image) # pixelmask
        self.rect = self.image.get_rect()
        self.rect.x = xpos
        self.rect.y = ypos
        self.x=xpos
        self.y=ypos
pygame.init()
clock = pygame.time.Clock()
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (50,50) #Set window position
SCREEN = pygame.display.set_mode((SCREENW, SCREENH))
clock = pygame.time.Clock()
pygame.display.set_caption('rotating object')
ball = pygame.image.load("ball.jpg")
pin=pygame.image.load("center.jpg");
platforms = pygame.sprite.Group()
center_x = SCREENW/2
center_y = SCREENH/2
radius = 200
angle = pi/4 # starting angle 45 degrees
omega = 0.1 #Angular velocity

#---------------------------------------------------------------------------------------
for _ in itertools.repeat(None, 6):
    xpos = center_x + radius * cos(angle) #Starting position x
    ypos = center_y - radius * sin(angle) #Startinh position y
    obj = object_factory(ball, xpos, ypos)
    obj.angle = angle
    obj.omega = omega  #angula velocity
    obj.radius = radius
    platforms.add(obj)
    angle += pi/3
#----------------------------------------------------------------------
while True:
    clock.tick(24)
    pygame.event.pump()
    keys = pygame.key.get_pressed()
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYDOWN and event.key ==
K_ESCAPE):
            pygame.quit()
            sys.exit()
    SCREEN.fill((255,255,255))
    SCREEN.blit(pin,(center_x, center_y))

#Class
implementation--------------------------------------------------------------------------------------------------------------
    for b in platforms:
        b.angle+=b.omega
        #Rect Base Rotation
        #b.rect.x += b.radius * b.omega * cos(b.angle + pi / 2)
        #b.rect.y -= b.radius * b.omega * sin(b.angle + pi / 2)
        #SCREEN.blit(ball,(b.rect.x,b.rect.y))

        # Normal
Rotation-------------------------------------------------------------------------------------------------------------
        b.x+=b.radius * b.omega * cos(b.angle + pi / 2)
        b.y-= b.radius * b.omega * sin(b.angle + pi / 2)
        SCREEN.blit(ball,(b.x,b.y))
    pygame.display.update()


On Wed, Apr 29, 2015 at 10:00 PM, Alan Gauld <alan.gauld at btinternet.com>
wrote:

> On 29/04/15 10:15, diliup gabadamudalige wrote:
>
>> x=42 good
>> x += 42 -x ?
>>
>> That does not go by a mile of what I asked.
>>
>
> You've asked three different things:
>
> 1) Why the += form gives different results from the assignment form,
> 2) Why some code you apparently wriotre worked outside a class
>    but not in a class
> 3) A specific question about some code for moving an object
>    in PyGame around in a circle
>
> Number 1 is the only one I can comment on as I can't see your attachments.
> That is what I (and several others) have answered.
> They are fundamentally different. There is no general way
> to make an augmented assignment such that
>
> x = f(y) and
> x += f(y)  (or even g(y))
>
> produce the same result except by the trivial
>
> x += g(y) - x
>
>  Alan, are you telling me that there is no way that one can arrive at X2
>> which is the NEXT place that X1 will be after "some increment"?
>> old x position = X1
>>
>
> No, that is a completely separate question and has nothing
> to do with using augmented assignment. But it does depend
> on the specifics of the situation and is mainly a mathematical
> problem rather than a Python one..
>
>  new x position= X1 + some increment value
>> which can be written as :new X = oldX + some increment value
>>
>> which can be simplified to X += some increment value?
>>
>
> That may or may not be possible, it depends on what the
> original equation in the pure assignment model is.
>
>  my orginal question was
>>
>> *Why does the object NOT move in a circle when implemented as a class?*
>>
>
> Your original question was:
>
> is there a way to do
> self.rect.x +*= some value*
> self.rect.y += some value
>
> rather than
>
> self.rect.x = self.radius * math.sin(self.angle) + self.center_x
> self.rect.y = self.radius * math.cos(self.angle) + self.center_y
>
> Which is about the use of augmented assignment.
>
>  All the code was provided.
>>
>
> No it wasn't. I have not seen any of your code because you persist
> in sending it as attachments which (as you've been told) do not
> work reliably in a text based mailing list. If you want
> comments on the code either post it inline in your message
> or as a link to a web site where we can all see it.
>
>  The above is  what I asked. (I hope this is clear enough)
>>
>
> Your class based code should work but without sight of it
> I cannot begin to guess about that aspect of your problem.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Diliup Gabadamudalige

http://www.diliupg.com
http://soft.diliupg.com/

**********************************************************************************************
This e-mail is confidential. It may also be legally privileged. If you are
not the intended recipient or have received it in error, please delete it
and all copies from your system and notify the sender immediately by return
e-mail. Any unauthorized reading, reproducing, printing or further
dissemination of this e-mail or its contents is strictly prohibited and may
be unlawful. Internet communications cannot be guaranteed to be timely,
secure, error or virus-free. The sender does not accept liability for any
errors or omissions.
**********************************************************************************************

From robertvstepp at gmail.com  Wed Apr 29 22:10:09 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 29 Apr 2015 15:10:09 -0500
Subject: [Tutor] Is there a way to store and later use comparison operators
 (<, <=, =, >=, >) ?
Message-ID: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>

Python 2.4.4, Solaris 10.

I have some functions that I believe I could collapse into a single
function if I only knew how:

def choose_compare(operator, value0, value1, pass_color, fail_color):
    """
    Perform the comparison indicated by operator. Return pass_color if
true, fail_color if false.
    """
    if operator == '<':
            return less_than(value0, value1, pass_color, fail_color)
    elif operator == '<=':
        return less_than_or_equal(value0, value1, pass_color, fail_color)
    elif operator == '=':
        return equal(value0, value1, pass_color, fail_color)
    elif operator == '>':
        return greater_than(value0, value1, pass_color, fail_color)
    elif operator == '>=':
        return greater_than_or_equal(value0, value1, pass_color, fail_color)
    else:
        print 'WarningMessage = "Invalid comparison operator in
function, choose_compare(). at Please contact script administrator for
assistance.";'

def less_than(value0, value1, pass_color, fail_color):
    """
    See if value0 is less than value1. If true, return pass_color. If
false, return fail_color.
    """
    if value0 < value1:
        return pass_color, True
    else:
        return fail_color, False

def less_than_or_equal(value0, value1, pass_color, fail_color):
    """
    See if value0 is less than or equal to value1. If true, return
pass_color. If false, return fail_color.
    """
    if value0 <= value1:
        return pass_color, True
    else:
        return fail_color, False

... 3 more functions ...

I won't give the remaining functions for the other comparison
operators. The string variable, operator, is originally populated from
a data file, which tells what type of comparison needs to be made. The
last two functions I gave (and the ones I omitted giving) all follow
the same exact pattern. I know there has to be some way to replace
these 5 functions with 1, but what experimentation I have done to date
has not worked.

Also, what about the first function above? I could use 2 dictionaries,
1 for calling the 5 functions and one to pass the arguments, but is it
worth doing this? Or, I would not be surprised if there is a much
better way! ~(:>))

Thanks!

-- 
boB

From marc.tompkins at gmail.com  Wed Apr 29 22:46:10 2015
From: marc.tompkins at gmail.com (Marc Tompkins)
Date: Wed, 29 Apr 2015 13:46:10 -0700
Subject: [Tutor] Is there a way to store and later use comparison
 operators (<, <=, =, >=, >) ?
In-Reply-To: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
References: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
Message-ID: <CAKK8jXagTTzw-E9Y6yxsCUOCQAvQU0hU9CcMQDG-WrTf+Y4hRA@mail.gmail.com>

On Wed, Apr 29, 2015 at 1:10 PM, boB Stepp <robertvstepp at gmail.com> wrote:

> Python 2.4.4, Solaris 10.
>
> I have some functions that I believe I could collapse into a single
> function if I only knew how:
>
> def choose_compare(operator, value0, value1, pass_color, fail_color):
>     """
>     Perform the comparison indicated by operator. Return pass_color if
> true, fail_color if false.
>     """
>     if operator == '<':
>             return less_than(value0, value1, pass_color, fail_color)
>     elif operator == '<=':
>         return less_than_or_equal(value0, value1, pass_color, fail_color)
>     elif operator == '=':
>         return equal(value0, value1, pass_color, fail_color)
>     elif operator == '>':
>         return greater_than(value0, value1, pass_color, fail_color)
>     elif operator == '>=':
>         return greater_than_or_equal(value0, value1, pass_color,
> fail_color)
>     else:
>         print 'WarningMessage = "Invalid comparison operator in
> function, choose_compare(). at Please contact script administrator for
> assistance.";'
>
> def less_than(value0, value1, pass_color, fail_color):
>     """
>     See if value0 is less than value1. If true, return pass_color. If
> false, return fail_color.
>     """
>     if value0 < value1:
>         return pass_color, True
>     else:
>         return fail_color, False
>
> def less_than_or_equal(value0, value1, pass_color, fail_color):
>     """
>     See if value0 is less than or equal to value1. If true, return
> pass_color. If false, return fail_color.
>     """
>     if value0 <= value1:
>         return pass_color, True
>     else:
>         return fail_color, False
>
> ... 3 more functions ...
>
> I won't give the remaining functions for the other comparison
> operators. The string variable, operator, is originally populated from
> a data file, which tells what type of comparison needs to be made. The
> last two functions I gave (and the ones I omitted giving) all follow
> the same exact pattern. I know there has to be some way to replace
> these 5 functions with 1, but what experimentation I have done to date
> has not worked.
>
> Also, what about the first function above? I could use 2 dictionaries,
> 1 for calling the 5 functions and one to pass the arguments, but is it
> worth doing this? Or, I would not be surprised if there is a much
> better way! ~(:>))
>
> Thanks!
>

Here's what I came up with:

def choose_compare(operator, value0, value1, pass_color, fail_color):
    comps = {"=":"==", "<":"<", ">":">", "<=":"<=", ">=":">="}
    if operator in comps.keys():
        operator = comps[operator]
        if eval("{} {} {}".format(value0, operator, value1)):
            return pass_color, True
        else:
            return fail_color, False
    else:
        print('WarningMessage')

I would ordinarily avoid eval() like the plague, but I think that this
sanitizes the input pretty effectively.  I had to make comps a dict instead
of a list because (in your example, anyway) you're using a single equals
sign to check for equality, which throws a Syntax Error (e.g.  "if 1 = 2"
instead of "if 1 == 2").

From roel at roelschroeven.net  Wed Apr 29 23:11:13 2015
From: roel at roelschroeven.net (Roel Schroeven)
Date: Wed, 29 Apr 2015 23:11:13 +0200
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
In-Reply-To: <mhr1n5$lj7$1@ger.gmane.org>
References: <55404A9D.5010103@gmail.com> <mhq3dh$lnt$1@ger.gmane.org>
 <554100DD.3080000@gmail.com> <mhr1n5$lj7$1@ger.gmane.org>
Message-ID: <mhrhdi$ba2$1@ger.gmane.org>

Alan Gauld schreef op 2015-04-29 18:43:
> On 29/04/15 17:03, Jugurtha Hadjar wrote:
>> http://docs.python-guide.org/en/latest/writing/style/#create-an-ignored-variable
> 
> I've seen this before and strongly disagree with it.

I disagree with your disagreement. I'll try to explain.

> They are ambiguous, difficult to remember, easy to overlook

I'm not sure what exactly you mean by that.

> and if you change your mind and decide you need to use it later
 > it's a whole new name to go back and introduce

True, but I don't see how that is a problem. At that point the variable 
is only used at one point, so you only have to rename it at that one place.

> (or worse be tempted to use the  meaningless symbol). 

That would be bad indeed, but I think a very minimal amount of 
discipline is enough to avoid that.

> And if you need another 'throw-away' name later you use the same one, then forget
 > here are two uses and try to use it anyway (even in debugging) and get
> completely wrong values, that may or may not look different
> to what you expect.

The whole point of ignored variables is that you don't use them. If you 
use them, they're not exactly ignored variables. It doesn't matter if 
you use __ once or twice or many times more; all of them are to be ignored.

 > (looking different is good - you can
 > detect it easily, looking similar is very, very, bad!)...
 > its just a horror story waiting to trip you up.

I'm not sure in what way __ can lead to horror stories. Do you have an 
example to fuel my imagination?

 > It's far better to have a short meaningful name that is never
 > used than a bland, meaningless, generic symbol.

By 'short meaningful name', do you mean something like 'dummy' or 
'ignorethis' as in

basename, dummy, ext = filename.rpartition('.')

or rather something like

basename, separator, ext = filename.rpartition('.')

In the first case, I prefer __ over dummy exactly because to me it's 
clearer at a glance that the name is one-use only and the value is to be 
ignored.
In the second case, using a 'real' name like 'separator' means I now 
have to mentally keep track of it since as far as I can see at that 
point it might be used later in the code.


To me, using _ or __ decreases the cognitive load because they tell me I 
don't have to remember anything about them, since they're not going to 
be used later. Read and forget.



Best regards,
Roel

-- 
The saddest aspect of life right now is that science gathers knowledge
faster than society gathers wisdom.
   -- Isaac Asimov

Roel Schroeven


From robertvstepp at gmail.com  Wed Apr 29 23:12:29 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 29 Apr 2015 16:12:29 -0500
Subject: [Tutor] Is there a way to store and later use comparison
 operators (<, <=, =, >=, >) ?
In-Reply-To: <CAKK8jXagTTzw-E9Y6yxsCUOCQAvQU0hU9CcMQDG-WrTf+Y4hRA@mail.gmail.com>
References: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
 <CAKK8jXagTTzw-E9Y6yxsCUOCQAvQU0hU9CcMQDG-WrTf+Y4hRA@mail.gmail.com>
Message-ID: <CANDiX9LDy2zZHtXqa_RGUO5r+wHF0kJLFnGACxfLJv3QDV=NMQ@mail.gmail.com>

On Wed, Apr 29, 2015 at 3:46 PM, Marc Tompkins <marc.tompkins at gmail.com> wrote:
> On Wed, Apr 29, 2015 at 1:10 PM, boB Stepp <robertvstepp at gmail.com> wrote:
>>
>> Python 2.4.4, Solaris 10.
>>
>> I have some functions that I believe I could collapse into a single
>> function if I only knew how:
>>
>> def choose_compare(operator, value0, value1, pass_color, fail_color):
>>     """
>>     Perform the comparison indicated by operator. Return pass_color if
>> true, fail_color if false.
>>     """
>>     if operator == '<':
>>             return less_than(value0, value1, pass_color, fail_color)
>>     elif operator == '<=':
>>         return less_than_or_equal(value0, value1, pass_color, fail_color)
>>     elif operator == '=':
>>         return equal(value0, value1, pass_color, fail_color)
>>     elif operator == '>':
>>         return greater_than(value0, value1, pass_color, fail_color)
>>     elif operator == '>=':
>>         return greater_than_or_equal(value0, value1, pass_color,
>> fail_color)
>>     else:
>>         print 'WarningMessage = "Invalid comparison operator in
>> function, choose_compare(). at Please contact script administrator for
>> assistance.";'
>>
>> def less_than(value0, value1, pass_color, fail_color):
>>     """
>>     See if value0 is less than value1. If true, return pass_color. If
>> false, return fail_color.
>>     """
>>     if value0 < value1:
>>         return pass_color, True
>>     else:
>>         return fail_color, False
>>
>> def less_than_or_equal(value0, value1, pass_color, fail_color):
>>     """
>>     See if value0 is less than or equal to value1. If true, return
>> pass_color. If false, return fail_color.
>>     """
>>     if value0 <= value1:
>>         return pass_color, True
>>     else:
>>         return fail_color, False
>>
>> ... 3 more functions ...
>>
>> I won't give the remaining functions for the other comparison
>> operators. The string variable, operator, is originally populated from
>> a data file, which tells what type of comparison needs to be made. The
>> last two functions I gave (and the ones I omitted giving) all follow
>> the same exact pattern. I know there has to be some way to replace
>> these 5 functions with 1, but what experimentation I have done to date
>> has not worked.
>>
>> Also, what about the first function above? I could use 2 dictionaries,
>> 1 for calling the 5 functions and one to pass the arguments, but is it
>> worth doing this? Or, I would not be surprised if there is a much
>> better way! ~(:>))
>>
>> Thanks!
>
>
> Here's what I came up with:
>
> def choose_compare(operator, value0, value1, pass_color, fail_color):
>     comps = {"=":"==", "<":"<", ">":">", "<=":"<=", ">=":">="}
>     if operator in comps.keys():
>         operator = comps[operator]
>         if eval("{} {} {}".format(value0, operator, value1)):
>             return pass_color, True
>         else:
>             return fail_color, False
>     else:
>         print('WarningMessage')
>
> I would ordinarily avoid eval() like the plague, but I think that this
> sanitizes the input pretty effectively.  I had to make comps a dict instead
> of a list because (in your example, anyway) you're using a single equals
> sign to check for equality, which throws a Syntax Error (e.g.  "if 1 = 2"
> instead of "if 1 == 2").

I could deal with the "=" issue by either reformatting my data file to
use "==" in place of "=", or when I parse the data file, do the
replacement there. A list instead of the dictionary looks a little
easier on my eyes.

The list has me so leery of eval and exec that I totally forgot about
this possibility! There are only two places in my program where I read
information directly into my program: 1) The data file, or 2) how the
user of the planning software names his regions of interest (ROI) in
the planning system software. I will reexamine my checks of (1). For
(2) the planning software already has its own checks, which would
filter out a lot. And I am checking the ROIs to see if they are
present in the data file *exactly* as given in the data file;
otherwise, I reject them.

So I have stumbled (With your gracious help!) into a legitimate use of eval()?

Many thanks, again!

-- 
boB

From robertvstepp at gmail.com  Wed Apr 29 23:16:01 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 29 Apr 2015 16:16:01 -0500
Subject: [Tutor] Is there a way to store and later use comparison
 operators (<, <=, =, >=, >) ?
In-Reply-To: <201504292050.t3TKo7e7024322@fido.openend.se>
References: <robertvstepp@gmail.com>
 <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
 <201504292050.t3TKo7e7024322@fido.openend.se>
Message-ID: <CANDiX9J4_hyoDjZJXrRBDoOdGwS7gJfGd5sRBW--Kn5-CDs6uw@mail.gmail.com>

On Wed, Apr 29, 2015 at 3:50 PM, Laura Creighton <lac at openend.se> wrote:
> I forget.  You are writing these things as functions rather than
> methods of a class, because you don't know how to use classes yet?

You forget nothing! ~(:>))

> Because you are absolutely correct that there are ways to simplify this,
> but if you don't know how to use classes yet, put this on hold until
> you do.  And this particular thing you want to do is not the optimal
> place to start learning about how to use classes.

Since the unittest module creating test classes, I have commenced
formal studying of this topic. But as you point out, not ready for it
yet!


-- 
boB

From breamoreboy at yahoo.co.uk  Wed Apr 29 23:42:40 2015
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 29 Apr 2015 22:42:40 +0100
Subject: [Tutor] Is there a way to store and later use comparison
 operators (<, <=, =, >=, >) ?
In-Reply-To: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
References: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
Message-ID: <mhrj8i$bu1$1@ger.gmane.org>

On 29/04/2015 21:10, boB Stepp wrote:
> Python 2.4.4, Solaris 10.
>
> I have some functions that I believe I could collapse into a single
> function if I only knew how:
>
> def choose_compare(operator, value0, value1, pass_color, fail_color):
>      """
>      Perform the comparison indicated by operator. Return pass_color if
> true, fail_color if false.
>      """
>      if operator == '<':
>              return less_than(value0, value1, pass_color, fail_color)
>      elif operator == '<=':
>          return less_than_or_equal(value0, value1, pass_color, fail_color)
>      elif operator == '=':
>          return equal(value0, value1, pass_color, fail_color)
>      elif operator == '>':
>          return greater_than(value0, value1, pass_color, fail_color)
>      elif operator == '>=':
>          return greater_than_or_equal(value0, value1, pass_color, fail_color)
>      else:
>          print 'WarningMessage = "Invalid comparison operator in
> function, choose_compare(). at Please contact script administrator for
> assistance.";'
>
> def less_than(value0, value1, pass_color, fail_color):
>      """
>      See if value0 is less than value1. If true, return pass_color. If
> false, return fail_color.
>      """
>      if value0 < value1:
>          return pass_color, True
>      else:
>          return fail_color, False
>
> def less_than_or_equal(value0, value1, pass_color, fail_color):
>      """
>      See if value0 is less than or equal to value1. If true, return
> pass_color. If false, return fail_color.
>      """
>      if value0 <= value1:
>          return pass_color, True
>      else:
>          return fail_color, False
>
> ... 3 more functions ...
>
> I won't give the remaining functions for the other comparison
> operators. The string variable, operator, is originally populated from
> a data file, which tells what type of comparison needs to be made. The
> last two functions I gave (and the ones I omitted giving) all follow
> the same exact pattern. I know there has to be some way to replace
> these 5 functions with 1, but what experimentation I have done to date
> has not worked.
>
> Also, what about the first function above? I could use 2 dictionaries,
> 1 for calling the 5 functions and one to pass the arguments, but is it
> worth doing this? Or, I would not be surprised if there is a much
> better way! ~(:>))
>
> Thanks!
>

This isn't a job for Bicycle Repair Man!!!  It smacks to me of 
dictionaries and the operator module but I'm too bone idle to look it up 
myself, so try here https://docs.python.org/3/library/operator.html
D'oh :)

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


From jugurtha.hadjar at gmail.com  Wed Apr 29 23:52:16 2015
From: jugurtha.hadjar at gmail.com (Jugurtha Hadjar)
Date: Wed, 29 Apr 2015 22:52:16 +0100
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
In-Reply-To: <mhq60p$263$1@ger.gmane.org>
References: <55404A9D.5010103@gmail.com> <mhq60p$263$1@ger.gmane.org>
Message-ID: <55415290.6080907@gmail.com>

On 04/29/2015 09:50 AM, Peter Otten wrote:
>
> My random observations:
>
> (1) find() and create() look very similar. Try hard to factor out common
> code. You might even combine it into a single method ensure_balance(phone).
>

I'll think about it. I can't see for now how I would combine the two 
(each are triggered by different sets of conditions), but there's 
probably a better way.

> (2) According to
>
> https://docs.python.org/dev/library/sqlite3.html#using-the-connection-as-a-context-manager
>
> - the context manager automatically commits
> - you can run sql directly on the connection
>

I read that but I can't recall for the life of me why I didn't use it 
that way. Maybe I didn't understand it well or something broke, etc. 
I'll look into it.

> It might by a good idea to refactor init_db() to just return the connection
> and then use it as
>
>      with self.init_db() as conn:
>          return conn.execute(
>              self.QUERIES['FIND_PHONE'],
>              (self.phone,)).fetchone() is not None
>
> If you need a cursor you can easily get one from the connection. If you want
> more complex handling later you can always turn init_db() into a
> contextmanager (see
> <https://docs.python.org/dev/library/contextlib.html#contextlib.contextmanager>
> ).
>

Yes, that's the way it was but I didn't like conn.cursor and I didn't 
know how to use context managers (still don't). So I wanted to have 
something working first, and then improving it now.


> (3) Catching Exception is overly broad. You will also catch a typo like
>
> cursor.execute(
>      self.QUERIES['CERATE'],
>      (self.phone, seed_balance)
> )
>
> where the proper fix is to modify the script. Only catch exceptions that you
> can actually handle. Example: a table doesn't exist, and you want to create
> it lazily on first access. Let all other exceptions just bubble up. It may
> seem lazy, but a complete traceback is invaluable for identifying and fixing
> a bug.
>

Right. This was also pointed by Alan so it must be really shabby. I'll 
look into it.

> (4) self.ERROR.format(e.args[0])
>
> is probably a string with len() > 0, and thus True in a boolean context.
>  From that follows an exception in the find() method in
>
>>                  self.known = self.find()
>
> causes the following if-suite to be run
>
>>                  if self.known:
>>                          self.balance = self.get_balance()
>
> and if get_balance() has a same idea of proper exception handling
>
> self.balance will end up containing an error message.

Nice, really nice :)

>
> (5) From point (4) I conclude that you don't have unit tests that cover your
> code. You should really write some of these before pondering about stylistic
> issues. Unit tests
>
> - help avoid errors
> - make changes in the code less of a gamble because if the tests succeed
> after the change you can be confident the change didn't introduce an error
> - what you might not expect: how drastically tests affect the style of your
> code. You'll see yourself thinking "How can I test that?" with every line of
> code that you write, and that alone will improve the quality of your code.
>

I have simple scripts that test for specific things, but it's not really 
professional neither does it follow any structure, etc.

I'll improve the code following the recommendations on this thread..

Thanks, Peter.

-- 
~Jugurtha Hadjar,

From diliupg at gmail.com  Wed Apr 29 22:19:59 2015
From: diliupg at gmail.com (diliup gabadamudalige)
Date: Thu, 30 Apr 2015 01:49:59 +0530
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <55412921.3050506@btinternet.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
 <mhq2c2$pr$1@ger.gmane.org>
 <CAMxbqSP51m7O45RwnSM1VY0MnCXH8majshwfC=_md7-YxP07XQ@mail.gmail.com>
 <554095BF.2000208@btinternet.com>
 <CAMxbqSOv+jTT0brUL1ny_irBMBsDzASS4cSqrqLtVJcjaUyO8w@mail.gmail.com>
 <mhr0v6$8cs$1@ger.gmane.org>
 <CAMxbqSM9R=-wXb-Ah6fErw0Z_tQTO0RxBGSUzd8tY0mz93yOgA@mail.gmail.com>
 <55412921.3050506@btinternet.com>
Message-ID: <CAMxbqSOkjD1PWGz7EmaMAcVFF6nHQK+zG6o9WzuB1598miw8Qg@mail.gmail.com>

Thanks Alan.

It is partly due to curiosity but I also wanted to have a common update
method. And as I almost always use the x+= some code, y+=some code for
animation stuff I wanted to know how it could be done using this method
rather than finding each position separately and assigning with x= some
code, y = some code (new position).

But here is STILL something curious in this whole matter.

If I update the rect positions with

obj.rect.x+ = some code
obj.rect.y+ = some code

then the rotation are NOT circular.
BUT
if I use

obj.x += some code
obj.y += some code

and then do

obj.rect.x, obj.rect.y = obj.x, obj.y

then the rotation works correct!!
This is really weird and I have no explanation as to why this happens!!!
Can you or anyone else explain this strange behaviour? After all a position
is a position.(at least that;s how I understand as long as you stick with
the same coordinate through out.)
The code is below.

import sys, os, pygame, itertools
from math import sin,cos,pi
from pygame.locals import *
SCREENW = 800
SCREENH = 700
class object_factory(pygame.sprite.Sprite):
    def __init__(self, image, xpos = 0, ypos = 0):
        """Constructor"""
        pygame.sprite.Sprite.__init__(self)
        self.image = image
        self.mask = pygame.mask.from_surface(self.image) # pixelmask
        self.rect = self.image.get_rect()
        self.rect.x = xpos
        self.rect.y = ypos
        self.x=xpos
        self.y=ypos
pygame.init()
clock = pygame.time.Clock()
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (50,50) #Set window position
SCREEN = pygame.display.set_mode((SCREENW, SCREENH))
clock = pygame.time.Clock()
pygame.display.set_caption('rotating object')
ball = pygame.image.load("ball.jpg")
pin=pygame.image.load("center.jpg");
platforms = pygame.sprite.Group()
center_x = SCREENW/2
center_y = SCREENH/2
radius = 200
angle = pi/4 # starting angle 45 degrees
omega = 0.1 #Angular velocity
for _ in itertools.repeat(None, 6):
    xpos = center_x + radius * cos(angle) #Starting position x
    ypos = center_y - radius * sin(angle) #Startinh position y
    obj = object_factory(ball, xpos, ypos)
    obj.angle = angle
    obj.omega = omega  #angula velocity
    obj.radius = radius
    platforms.add(obj)
    angle += pi/.5
#----------------------------------------------------------------------
while True:
    clock.tick(24)
    pygame.event.pump()
    keys = pygame.key.get_pressed()
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYDOWN and event.key ==
K_ESCAPE):
            pygame.quit()
            sys.exit()
    SCREEN.fill((0, 0, 0))
    SCREEN.blit(pin,(center_x - pin.get_width() / 2, center_y -
pin.get_height() / 2))
    pygame.draw.circle(SCREEN, (0, 0, 255), (center_x, center_y), radius, 2)

    for b in platforms:
        b.angle+=b.omega
        #Rect Base Rotation
        #b.rect.x += b.radius * b.omega * cos(b.angle + pi / 2)
        #b.rect.y -= b.radius * b.omega * sin(b.angle + pi / 2)
        #SCREEN.blit(ball,(b.rect.x,b.rect.y))
        #Normal Rotation
        b.x+= b.radius * b.omega * cos(b.angle + pi / 2)
        b.y-= b.radius * b.omega * sin(b.angle + pi / 2)

        b.rect.x, b.rect.y = b.x - b.rect.width / 2, b.y - b.rect.height / 2

        #SCREEN.blit(ball,(b.x,b.y)) # this and the line below gives the
same result
        #SCREEN.blit(ball, (b.rect.x, b.rect.y))

    platforms.update()
    platforms.draw(SCREEN)

    pygame.time.wait(100)
    pygame.display.update()



On Thu, Apr 30, 2015 at 12:25 AM, Alan Gauld <alan.gauld at btinternet.com>
wrote:

> On 29/04/15 19:37, diliup gabadamudalige wrote:
>
>> I do not understand how Alan does not get the code
>>
>
>
> Replying off list.
>
> I don't get it because text based email systems often strip out attachments
> since they are a security risk. As the name says they are *text* based.
>
> However, now that I've seen it and I see your solution I can better
> understand
> what you were trying to ask, which was the solution to a very specific
> scenario.
>
> I'm still not sure why you wanted to use augmented assignment, other
> than curiosity perhaps, but at least I now see what you were trying to do.
> Thanks for posting the solution.
>
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>


-- 
Diliup Gabadamudalige

http://www.diliupg.com
http://soft.diliupg.com/

**********************************************************************************************
This e-mail is confidential. It may also be legally privileged. If you are
not the intended recipient or have received it in error, please delete it
and all copies from your system and notify the sender immediately by return
e-mail. Any unauthorized reading, reproducing, printing or further
dissemination of this e-mail or its contents is strictly prohibited and may
be unlawful. Internet communications cannot be guaranteed to be timely,
secure, error or virus-free. The sender does not accept liability for any
errors or omissions.
**********************************************************************************************

From lac at openend.se  Wed Apr 29 22:50:07 2015
From: lac at openend.se (Laura Creighton)
Date: Wed, 29 Apr 2015 22:50:07 +0200
Subject: [Tutor] Is there a way to store and later use comparison
	operators (<, <=, =, >=, >) ?
In-Reply-To: Message from boB Stepp <robertvstepp@gmail.com> of "Wed,
 29 Apr 2015 15:10:09 -0500."
 <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
References: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
Message-ID: <201504292050.t3TKo7e7024322@fido.openend.se>

I forget.  You are writing these things as functions rather than
methods of a class, because you don't know how to use classes yet?

Because you are absolutely correct that there are ways to simplify this,
but if you don't know how to use classes yet, put this on hold until
you do.  And this particular thing you want to do is not the optimal
place to start learning about how to use classes.

Laura


From dyoo at hashcollision.org  Thu Apr 30 00:10:00 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Wed, 29 Apr 2015 15:10:00 -0700
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSM9R=-wXb-Ah6fErw0Z_tQTO0RxBGSUzd8tY0mz93yOgA@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
 <mhq2c2$pr$1@ger.gmane.org>
 <CAMxbqSP51m7O45RwnSM1VY0MnCXH8majshwfC=_md7-YxP07XQ@mail.gmail.com>
 <554095BF.2000208@btinternet.com>
 <CAMxbqSOv+jTT0brUL1ny_irBMBsDzASS4cSqrqLtVJcjaUyO8w@mail.gmail.com>
 <mhr0v6$8cs$1@ger.gmane.org>
 <CAMxbqSM9R=-wXb-Ah6fErw0Z_tQTO0RxBGSUzd8tY0mz93yOgA@mail.gmail.com>
Message-ID: <CAGZAPF4hPe_kY9QXiiAHyL3H9rzuew3vNPuc1LepmXssg-SCYw@mail.gmail.com>

On Wed, Apr 29, 2015 at 11:37 AM, diliup gabadamudalige
<diliupg at gmail.com> wrote:
> I do not understand how Alan does not get the code that is in this thread.

Hi Dilliup,

Please try to avoid using the phrase, "I don't understand how <X> does
not get <Y>...".


You might not realize it, but it's radioactive: it's has a very
negative connotation that is toxic to collaborative communities.

For more information on this, there's a very good book called Team
Geek that talks about these issues:

    https://books.google.com/books/about/Team_Geek.html?id=Iwk_pKeBc9gC&hl=en

Also see Hacker School's Social Rules:

    https://www.recurse.com/manual#sub-sec-social-rules


Thanks!

From alan.gauld at btinternet.com  Thu Apr 30 00:21:08 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Apr 2015 23:21:08 +0100
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSOkjD1PWGz7EmaMAcVFF6nHQK+zG6o9WzuB1598miw8Qg@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
 <mhq2c2$pr$1@ger.gmane.org>
 <CAMxbqSP51m7O45RwnSM1VY0MnCXH8majshwfC=_md7-YxP07XQ@mail.gmail.com>
 <554095BF.2000208@btinternet.com>
 <CAMxbqSOv+jTT0brUL1ny_irBMBsDzASS4cSqrqLtVJcjaUyO8w@mail.gmail.com>
 <mhr0v6$8cs$1@ger.gmane.org>
 <CAMxbqSM9R=-wXb-Ah6fErw0Z_tQTO0RxBGSUzd8tY0mz93yOgA@mail.gmail.com>
 <55412921.3050506@btinternet.com>
 <CAMxbqSOkjD1PWGz7EmaMAcVFF6nHQK+zG6o9WzuB1598miw8Qg@mail.gmail.com>
Message-ID: <mhrlgi$ipp$1@ger.gmane.org>

On 29/04/15 21:19, diliup gabadamudalige wrote:

> It is partly due to curiosity but I also wanted to have a common update
> method. And as I almost always use the x+= some code, y+=some code for
> animation stuff I wanted to know how it could be done using this method
> rather than finding each position separately and assigning with x= some
> code, y = some code (new position).

OK, Curiosity is good.
But the conversion is mainly a math challenge rather than a
programming one. And its a very seductive but dangerous mind
set to try to force a problem into a pattern that fits how
you usually do it. Especially if the transformed code looks
less intuitive than the original.

When I started in Python it didn't even have the += style
of augmented assignment, it was mainly introduced to save
some typing, nothing more.

Remember that += is still an assignment to x. It is not
significantly different or in any way 'better' than
the standard assignment. In languages like C '+='  (and
even more so '++' which doesn't exist in Python) used to
result in performance improvements but optimising
compilers have removed even that reason for using it.
Now it should just be considered a typing shortcut.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From __peter__ at web.de  Thu Apr 30 00:32:57 2015
From: __peter__ at web.de (Peter Otten)
Date: Thu, 30 Apr 2015 00:32:57 +0200
Subject: [Tutor] Good name(s) for to-be-ignored variables,
	was Re: Good Taste Question: Using SQLite3 in Python
References: <55404A9D.5010103@gmail.com> <mhq3dh$lnt$1@ger.gmane.org>
 <554100DD.3080000@gmail.com> <mhr1n5$lj7$1@ger.gmane.org>
 <mhrhdi$ba2$1@ger.gmane.org>
Message-ID: <mhrm6r$ush$1@ger.gmane.org>

Roel Schroeven wrote:

> Alan Gauld schreef op 2015-04-29 18:43:
>> On 29/04/15 17:03, Jugurtha Hadjar wrote:
>>> http://docs.python-guide.org/en/latest/writing/style/#create-an-ignored-variable
>> 
>> I've seen this before and strongly disagree with it.
> 
> I disagree with your disagreement. I'll try to explain.
> 
>> They are ambiguous, difficult to remember, easy to overlook
> 
> I'm not sure what exactly you mean by that.
> 
>> and if you change your mind and decide you need to use it later
>  > it's a whole new name to go back and introduce
> 
> True, but I don't see how that is a problem. At that point the variable
> is only used at one point, so you only have to rename it at that one
> place.
> 
>> (or worse be tempted to use the  meaningless symbol).
> 
> That would be bad indeed, but I think a very minimal amount of
> discipline is enough to avoid that.
> 
>> And if you need another 'throw-away' name later you use the same one,
>> then forget
>  > here are two uses and try to use it anyway (even in debugging) and get
>> completely wrong values, that may or may not look different
>> to what you expect.
> 
> The whole point of ignored variables is that you don't use them. If you
> use them, they're not exactly ignored variables. It doesn't matter if
> you use __ once or twice or many times more; all of them are to be
> ignored.
> 
>  > (looking different is good - you can
>  > detect it easily, looking similar is very, very, bad!)...
>  > its just a horror story waiting to trip you up.
> 
> I'm not sure in what way __ can lead to horror stories. Do you have an
> example to fuel my imagination?
> 
>  > It's far better to have a short meaningful name that is never
>  > used than a bland, meaningless, generic symbol.
> 
> By 'short meaningful name', do you mean something like 'dummy' or
> 'ignorethis' as in
> 
> basename, dummy, ext = filename.rpartition('.')
> 
> or rather something like
> 
> basename, separator, ext = filename.rpartition('.')
> 
> In the first case, I prefer __ over dummy exactly because to me it's
> clearer at a glance that the name is one-use only and the value is to be
> ignored.
> In the second case, using a 'real' name like 'separator' means I now
> have to mentally keep track of it since as far as I can see at that
> point it might be used later in the code.
> 
> 
> To me, using _ or __ decreases the cognitive load because they tell me I
> don't have to remember anything about them, since they're not going to
> be used later. Read and forget.

Inside a function there's a middle ground, a leading underscore:

def whatever():
    ...
    basename, _extsep, ext = filename.rpartition(os.extsep)
    ...

The name makes it clear what _extsep is supposed to contain, and the 
underscore indicates that you are not using the name.

You can later question the decision that you are not interested in _extsep 
-- in the example you may decide that you want to discriminate between

"somefile." and "somefile"

Even if you stick with the original design I find it more readable to state 
explicitly what you are throwing away. 

My whatever() function is an example where the name of the to-be-ignored 
variable led to a change in the code: I started with _separator and then 
remembered that the separator need not be a dot.

Admittedly I don't expect to use an OS where os.extsep != "." anytime soon, 
but you get the idea...


From __peter__ at web.de  Thu Apr 30 00:49:12 2015
From: __peter__ at web.de (Peter Otten)
Date: Thu, 30 Apr 2015 00:49:12 +0200
Subject: [Tutor] Is there a way to store and later use comparison
	operators (<, <=, =, >=, >) ?
References: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
 <CAKK8jXagTTzw-E9Y6yxsCUOCQAvQU0hU9CcMQDG-WrTf+Y4hRA@mail.gmail.com>
 <CANDiX9LDy2zZHtXqa_RGUO5r+wHF0kJLFnGACxfLJv3QDV=NMQ@mail.gmail.com>
Message-ID: <mhrn58$cfc$1@ger.gmane.org>

boB Stepp wrote:

> On Wed, Apr 29, 2015 at 3:46 PM, Marc Tompkins <marc.tompkins at gmail.com>
> wrote:
>> On Wed, Apr 29, 2015 at 1:10 PM, boB Stepp <robertvstepp at gmail.com>
>> wrote:
>>>
>>> Python 2.4.4, Solaris 10.
>>>
>>> I have some functions that I believe I could collapse into a single
>>> function if I only knew how:
>>>
>>> def choose_compare(operator, value0, value1, pass_color, fail_color):
>>>     """
>>>     Perform the comparison indicated by operator. Return pass_color if
>>> true, fail_color if false.
>>>     """
>>>     if operator == '<':
>>>             return less_than(value0, value1, pass_color, fail_color)
>>>     elif operator == '<=':
>>>         return less_than_or_equal(value0, value1, pass_color,
>>>         fail_color)
>>>     elif operator == '=':
>>>         return equal(value0, value1, pass_color, fail_color)
>>>     elif operator == '>':
>>>         return greater_than(value0, value1, pass_color, fail_color)
>>>     elif operator == '>=':
>>>         return greater_than_or_equal(value0, value1, pass_color,
>>> fail_color)
>>>     else:
>>>         print 'WarningMessage = "Invalid comparison operator in
>>> function, choose_compare(). at Please contact script administrator for
>>> assistance.";'
>>>
>>> def less_than(value0, value1, pass_color, fail_color):
>>>     """
>>>     See if value0 is less than value1. If true, return pass_color. If
>>> false, return fail_color.
>>>     """
>>>     if value0 < value1:
>>>         return pass_color, True
>>>     else:
>>>         return fail_color, False
>>>
>>> def less_than_or_equal(value0, value1, pass_color, fail_color):
>>>     """
>>>     See if value0 is less than or equal to value1. If true, return
>>> pass_color. If false, return fail_color.
>>>     """
>>>     if value0 <= value1:
>>>         return pass_color, True
>>>     else:
>>>         return fail_color, False
>>>
>>> ... 3 more functions ...
>>>
>>> I won't give the remaining functions for the other comparison
>>> operators. The string variable, operator, is originally populated from
>>> a data file, which tells what type of comparison needs to be made. The
>>> last two functions I gave (and the ones I omitted giving) all follow
>>> the same exact pattern. I know there has to be some way to replace
>>> these 5 functions with 1, but what experimentation I have done to date
>>> has not worked.
>>>
>>> Also, what about the first function above? I could use 2 dictionaries,
>>> 1 for calling the 5 functions and one to pass the arguments, but is it
>>> worth doing this? Or, I would not be surprised if there is a much
>>> better way! ~(:>))
>>>
>>> Thanks!
>>
>>
>> Here's what I came up with:
>>
>> def choose_compare(operator, value0, value1, pass_color, fail_color):
>>     comps = {"=":"==", "<":"<", ">":">", "<=":"<=", ">=":">="}
>>     if operator in comps.keys():
>>         operator = comps[operator]
>>         if eval("{} {} {}".format(value0, operator, value1)):
>>             return pass_color, True
>>         else:
>>             return fail_color, False
>>     else:
>>         print('WarningMessage')
>>
>> I would ordinarily avoid eval() like the plague, but I think that this
>> sanitizes the input pretty effectively.  I had to make comps a dict
>> instead of a list because (in your example, anyway) you're using a single
>> equals
>> sign to check for equality, which throws a Syntax Error (e.g.  "if 1 = 2"
>> instead of "if 1 == 2").
> 
> I could deal with the "=" issue by either reformatting my data file to
> use "==" in place of "=", or when I parse the data file, do the
> replacement there. A list instead of the dictionary looks a little
> easier on my eyes.
> 
> The list has me so leery of eval and exec that I totally forgot about
> this possibility! There are only two places in my program where I read
> information directly into my program: 1) The data file, or 2) how the
> user of the planning software names his regions of interest (ROI) in
> the planning system software. I will reexamine my checks of (1). For
> (2) the planning software already has its own checks, which would
> filter out a lot. And I am checking the ROIs to see if they are
> present in the data file *exactly* as given in the data file;
> otherwise, I reject them.
> 
> So I have stumbled (With your gracious help!) into a legitimate use of
> eval()?

No. To expand on Marks hint here's how to do it without evil eval().

import operator

comps = {
    "=": operator.eq,
    "<": operator.lt,
    ">": operator.gt,
    # ...
}

def choose_compare(operator, value0, value1, pass_color, fail_color):
    op = comps[operator]
    if op(value0, value1):
        return pass_color, True
    else:
        return fail_color, False

print(choose_compare("=", 1, 1, "red", "blue"))
print(choose_compare("<", 1, 2, "red", "blue"))
print(choose_compare("<", 2, 1, "red", "blue"))

Rule of thumb: when you think you need eval() you're wrong.


From alan.gauld at btinternet.com  Thu Apr 30 00:51:17 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Apr 2015 23:51:17 +0100
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
In-Reply-To: <mhrhdi$ba2$1@ger.gmane.org>
References: <55404A9D.5010103@gmail.com> <mhq3dh$lnt$1@ger.gmane.org>
 <554100DD.3080000@gmail.com> <mhr1n5$lj7$1@ger.gmane.org>
 <mhrhdi$ba2$1@ger.gmane.org>
Message-ID: <mhrn92$gc6$1@ger.gmane.org>

On 29/04/15 22:11, Roel Schroeven wrote:
> Alan Gauld schreef op 2015-04-29 18:43:
>> On 29/04/15 17:03, Jugurtha Hadjar wrote:
>>> http://docs.python-guide.org/en/latest/writing/style/#create-an-ignored-variable
>>>
>>
>> I've seen this before and strongly disagree with it.
>
> I disagree with your disagreement. I'll try to explain.
>
>> They are ambiguous, difficult to remember, easy to overlook
>
> I'm not sure what exactly you mean by that.

If something exists in a function, over time somebody will use it.
Especially during debugging, priont is a dangerous tool in these cases.
Simple fact of life. If it exists it should be visible (not too
short or incongruous) Trying to visually scan for _ or even
__ is hard. Also different fonts make _ and __ hard to
distinguish.

>> and if you change your mind and decide you need to use it later
>  > it's a whole new name to go back and introduce
>
> True, but I don't see how that is a problem. At that point the variable
> is only used at one point, so you only have to rename it at that one place.

It is if its only used once - see below.
Renaming the wrong variable (especially ising search./replace
in the editor) is a very common way to introduce new bugs into
working code! Having spent nearly 10 years running 3 different 
maintenance teams I know how easy it is for new programmers(*)
to start changing things they don;t understand, especially
when under time pressure.

(*)And maintenance teams are almost always comprised of a
combination of new or very old (read jaded) programmers.
The top players are reserved for the exciting new stuff!

>> (or worse be tempted to use the  meaningless symbol).
>
> That would be bad indeed, but I think a very minimal amount of
> discipline is enough to avoid that.

Its almost impossible,  A maintenance team is usually working
on a ratio of 10-50,000 lines of code per programmer per project
and typically 3-5 projects. So if you have to hold 50-150,000
lines of code in mind its very easy to slip something in as
a 'quick fix' intending to fix it next time then forget about
it. Especially if you have to check in two bug fixes before
you get to go home tonight....

Maintenance programmers are rarely the people who wrote the
code, and they rarely have much personal pride invested in
the code they have to fix. Even if they are the original
developer they will have moved on to new projects and
fixing 5 year old code is a low priority. Its all about
human nature.


> The whole point of ignored variables is that you don't use them.

That's the point when they are created, but too often a
use is found for these things. The original author is never in a 
position to say 'this will never be used in the future'
that's just too idealistic. And the original author is
very unlikely to be the long tem maintainer. Even in
open-source where people tend to stick with projects
for a few years its not true. In commercial code the
author probably leaves the company within 6 months of
writing the code. He may never even see it go into
production...

> use them, they're not exactly ignored variables. It doesn't matter if
> you use __ once or twice or many times more; all of them are to be ignored.

Absolutely. nothing can be guaranteed to be ignored over
time, to start out with tat asumption is tom lay the seeds
of chaos later.

>  > (looking different is good - you can
>  > detect it easily, looking similar is very, very, bad!)...
>  > its just a horror story waiting to trip you up.
>
> I'm not sure in what way __ can lead to horror stories. Do you have an
> example to fuel my imagination?

None in Python - I've never run a Python maintenance squad,
but I have led assembler, C/C++, SQL, Perl and COBOL: teams.
In every case there have been attempts to use variables that
had been intended to be unused - in some cases randomly 
initialized/unassigned, reassigned etc. I once saw a C
function with the same dummy variable use 4 times - although
that did have a name, but it was a placeholder like x.

But in Perl I've seen the infamous $_ abused many times
(although that's slightly different since it magically takes
on certain values, implicit rather than explicit) Python tries
to avoid these things but the whole _/__ variable scheme is
IMHO one of its worst features.

>  > It's far better to have a short meaningful name that is never
>  > used than a bland, meaningless, generic symbol.
>
> By 'short meaningful name', do you mean something like 'dummy' or
> 'ignorethis' as in
>
> basename, dummy, ext = filename.rpartition('.')
>
> or rather something like
>
> basename, separator, ext = filename.rpartition('.')
>

The latter. or even 'sep' as shorter than 'separator'. At least
it gives some clue to its meaning and can be used later
if needed. Because its not expected to be used typing the
few extra characters once doesn't hurt. But it makes
scaffold code, debug code and extension code much easier
to write.

> In the first case, I prefer __ over dummy exactly because to me it's
> clearer at a glance that the name is one-use only and the value is to be
> ignored.

The intent may be clearer but dummy is much easier to
scan, search for and spot visually.

> In the second case, using a 'real' name like 'separator' means I now
> have to mentally keep track of it since as far as I can see at that
> point it might be used later in the code.

It will get reused anyhow, just accept that and give it a sensible name. 
If you don't intend to use it ignore it.

> To me, using _ or __ decreases the cognitive load because they tell me I
> don't have to remember anything about them, since they're not going to
> be used later. Read and forget.

But they will be. Almost for certain. It's human nature and the nature 
of code maintenance. If it's there somebody will find a use for it. The 
fact that 5 or 10 years earlier the author didn't intend for it to be 
used is immaterial.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From eryksun at gmail.com  Thu Apr 30 01:12:34 2015
From: eryksun at gmail.com (eryksun)
Date: Wed, 29 Apr 2015 18:12:34 -0500
Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths
In-Reply-To: <1430326451.93582.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
References: <1430326451.93582.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
Message-ID: <CACL+1asCGrw01Y3DO6qs9jTnWgqDWb-2ELtiU96p0FUyawbvSw@mail.gmail.com>

On Wed, Apr 29, 2015 at 11:54 AM, Albert-Jan Roskam
<fomcl at yahoo.com.dmarc.invalid> wrote:
> Hmmm, that sounds pretty convincing indeed (makes it even stranger that CD works the way it works).
> I believe it threw a WindowsError, indicating that the file(s) could not be found, because the dir was
> not changed. I actually first ran into this problem with this script, so with my current script I
> immediately refrained from using cwd:
> http://code.activestate.com/recipes/578883-git-pre-commit-hook-to-reject-large-files-using-py/
> Git gave a fatal error in windows and the pushd/popd fixed it.

I don't see why you'd need shell=True. Windows supports UNC paths in
the working directory, but the cmd.exe shell (being a crusty relic of
the 1980s) does not. So just use the default value, shell=False.
(However, on POSIX systems, unlike Windows, using shell=False requires
`cmd` to be a list.) BTW, there's no need to explicitly pass
cwd=os.getcwd(). The default behavior is to inherit the working
directory of the current process.

From dyoo at hashcollision.org  Thu Apr 30 01:52:53 2015
From: dyoo at hashcollision.org (Danny Yoo)
Date: Wed, 29 Apr 2015 16:52:53 -0700
Subject: [Tutor] Is there a way to store and later use comparison
 operators (<, <=, =, >=, >) ?
In-Reply-To: <mhrn58$cfc$1@ger.gmane.org>
References: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
 <CAKK8jXagTTzw-E9Y6yxsCUOCQAvQU0hU9CcMQDG-WrTf+Y4hRA@mail.gmail.com>
 <CANDiX9LDy2zZHtXqa_RGUO5r+wHF0kJLFnGACxfLJv3QDV=NMQ@mail.gmail.com>
 <mhrn58$cfc$1@ger.gmane.org>
Message-ID: <CAGZAPF4P1J6bka01en1P39zwtSn7zCRxECfCsZ_TbxEnJBeDFw@mail.gmail.com>

Hi Bob,

By the way, it sounds like you're starting to learn about how to write
interpreters.  If that's the case, you might find PLAI helpful:

    http://cs.brown.edu/~sk/Publications/Books/ProgLangs/

helpful.  (Full disclosure: the author was my external advisor.  :P)


Another good book is EoPL:

    http://www.amazon.com/Essentials-Programming-Languages-Daniel-Friedman/dp/0262062798


I have fond memories of those two books.

From alan.gauld at btinternet.com  Thu Apr 30 02:08:13 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 30 Apr 2015 01:08:13 +0100
Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths
In-Reply-To: <CACL+1asCGrw01Y3DO6qs9jTnWgqDWb-2ELtiU96p0FUyawbvSw@mail.gmail.com>
References: <1430326451.93582.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
 <CACL+1asCGrw01Y3DO6qs9jTnWgqDWb-2ELtiU96p0FUyawbvSw@mail.gmail.com>
Message-ID: <mhrrpa$jjo$1@ger.gmane.org>

On 30/04/15 00:12, eryksun wrote:

> the working directory, but the cmd.exe shell (being a crusty relic of
> the 1980s) does not.

Actually cmd.exe is fine with UNC paths. It's only when you
combine them with Windows /option style that it has issues
but even then putting the path in quotes will usually do
the trick.

It's the old MS-DOS COMMAND.COM that can't cope.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From eryksun at gmail.com  Thu Apr 30 02:48:19 2015
From: eryksun at gmail.com (eryksun)
Date: Wed, 29 Apr 2015 19:48:19 -0500
Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths
In-Reply-To: <mhrrpa$jjo$1@ger.gmane.org>
References: <1430326451.93582.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
 <CACL+1asCGrw01Y3DO6qs9jTnWgqDWb-2ELtiU96p0FUyawbvSw@mail.gmail.com>
 <mhrrpa$jjo$1@ger.gmane.org>
Message-ID: <CACL+1auqWH0NakimATPKYP-HSDPugCDvS25P3pX4fL4=LdvdyQ@mail.gmail.com>

On Wed, Apr 29, 2015 at 7:08 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 30/04/15 00:12, eryksun wrote:
>
>> the working directory, but the cmd.exe shell (being a crusty relic of
>> the 1980s) does not.
>
> Actually cmd.exe is fine with UNC paths. It's only when you
> combine them with Windows /option style that it has issues
> but even then putting the path in quotes will usually do
> the trick.
>
> It's the old MS-DOS COMMAND.COM that can't cope.

cmd.exe was developed for OS/2 (1987) to replace COMMAND.COM (1981).

cmd.exe cannot use a UNC path as the current directory. What it can do
is `pushd` a UNC path, which mounts it as a drive letter. If you do
try to start cmd.exe with a UNC path as the working directory, it
instead sets the working directory to the Windows directory. For
example:

    (test) C:\Temp>python
    Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  6 2014, 22:16:31)
    [MSC v.1600 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, subprocess
    >>> os.chdir(r'\\127.0.0.1\C$')
    >>> subprocess.call('cmd')
    '\\127.0.0.1\C$'
    CMD.EXE was started with the above path as the current directory.
    UNC paths are not supported.  Defaulting to Windows directory.
    Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

    (test) C:\Windows>

From cybervigilante at gmail.com  Thu Apr 30 03:05:29 2015
From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP)
Date: Wed, 29 Apr 2015 18:05:29 -0700
Subject: [Tutor] raise exception works as planned in program but not when
 imported into testing module
Message-ID: <CALRAYNUAdy8NkUQuWyoq-e+y3NMaU06di5pf6gNNo6ddZFbfew@mail.gmail.com>

I raised an exception in the parse_string function in my math parser
program, function_tosser.py, and caught it in the calling routine, and that
worked fine. But when I imported function_tosser.py into a test program,
tester.py, it threw the exception in the parse_string function instead of
handling it in the try block in the calling routine. Why did it work in one
and not the other? The testing program works fine if I return None as I did
before, instead of raising the exception.

# function_tosser.py
"""
Takes the name of a binary math operation and two numbers from input,
repeatedly, and displays the results until done
"""


def add(a, b):
    return a + b


def subtract(a, b):
    return b - a

def minus(a, b):
    return a - b


def multiply(a, b):
    return a * b


def divide(a, b):
    return a / b


operations = {'add': add, '+': add, 'plus': add, 'subtract': subtract,
'subtracted': subtract,
              '-': minus, 'minus': minus, 'multiply': multiply, '*':
multiply, 'multiplied': multiply,
              'times': multiply, 'divide': divide, '/': divide, 'divided':
divide}

def test_number(astring):
    """
    Input: A string that should represent a valid int or float. Output:
    An int or float on success. None on failure.
    """
    for make_type in (int, float):
        try:
            return make_type(astring)
        except ValueError: # Previously returned None, which worked. This
works fine here but when imported into the test program
            pass           # it doesn't wait for the try block in the
calling routine.
    return None


def parse_string(math_string):
    """Input: A math string with a verbal or mathematical operation
    and two valid numbers to operate on. Extra numbers and operations
    are ignored. Output: A tuple containing a function corresponding
    to the operation and the two numbers. Returns None on failure.
    """
    operation = None
    tokens = math_string.split()
    numbers = []
    for token in tokens:
        if token in operations:
            operation = operations[token]
        elif test_number(token) != None:
            numbers.append(test_number(token))
        if len(numbers) > 1:
            break
    if operation is None or len(numbers) < 2:
        raise ValueError
    else:
        return operation, numbers[0], numbers[1]

if __name__ == "__main__":
    instructions = '''Enter two numbers and one of the four basid math
operations,
    either mathematical or verbal. i.e. 3 + 2, 12 divided by 14, 10 minus
4, etc.
    Enter done to quit.
    '''
    try:
        user_input = input(instructions)
        while True:
            if user_input == 'done':
                break
            try:
                result = parse_string(user_input)
            except ValueError:
                print("Not a valid math operation.")
            else:
                func, num1, num2 = result
                print(func(num1, num2))
            user_input = input()
    except KeyboardInterrupt:
        print("Program terminated by user")

# tester.py

'''Test function_tosser.py mainlogic against random operators, operands,
and bad input'''
import random
import function_tosser as ft
valid_terms = list(ft.operations.keys())
def eval_test():
    pass

trash = ['1 +', 'blah', '3-4', 'gargle', 'Newt Gingrich',
    ",,,,,", '{+=-33.44 minus12 3 times blarg 1445641654644555455']

for ctr in range(50):
    term = ' ' + random.choice(valid_terms) + ' '
    num1 = str(random.randint(1,1000))
    num2 = str(random.randint(1,1000))
    if term == ' subtract ' or term == ' subtracted ': term = ' subtracted
from '
    if ctr % 10 == 0: # stress testing for a None failure
        monkey_wrench = random.choice(trash)
        print(ft.parse_string(monkey_wrench), '\n')
    else:
        func, num1, num2 = ft.parse_string(num1 + term + num2)
        print(func, num1, term, num2)
        print('result:',func(num1, num2), '\n')


-- 
Jim

"What a rotten, failed experiment. I'll start over. Maybe dogs instead of
monkeys this time." --God

From eryksun at gmail.com  Thu Apr 30 03:28:13 2015
From: eryksun at gmail.com (eryksun)
Date: Wed, 29 Apr 2015 20:28:13 -0500
Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths
In-Reply-To: <CACL+1auqWH0NakimATPKYP-HSDPugCDvS25P3pX4fL4=LdvdyQ@mail.gmail.com>
References: <1430326451.93582.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
 <CACL+1asCGrw01Y3DO6qs9jTnWgqDWb-2ELtiU96p0FUyawbvSw@mail.gmail.com>
 <mhrrpa$jjo$1@ger.gmane.org>
 <CACL+1auqWH0NakimATPKYP-HSDPugCDvS25P3pX4fL4=LdvdyQ@mail.gmail.com>
Message-ID: <CACL+1asg31UUTSwXajGC7MrzPd6bDdmAoA5ej-K51q93pyeQuQ@mail.gmail.com>

On Wed, Apr 29, 2015 at 7:48 PM, eryksun <eryksun at gmail.com> wrote:
> cmd.exe was developed for OS/2 (1987) to replace COMMAND.COM (1981).

Actually, I stand corrected about the reason being cmd's 1980s
crustiness. Per [KB156276][1] this check was added to NT 4.0 (1996) to
address a vaguely described problem ("a UNC name may cause problems
with child processes launched from such a console when that console is
exited or halted"), which may not even be a problem nowadays (Windows
7+) since the console was moved out of CSRSS.EXE (the Windows session
server) into instances of conhost.exe that run in the security context
of the client. Try adding the registry setting to disable this check.
Probably nothing bad will happen. Here's a reg.exe command to disable
the check for the current user:

    reg add "HKCU\Software\Microsoft\Command Processor"
        /v DisableUNCCheck /t REG_DWORD /d 1

After disabling the check, my previous example should work fine:

    (test) C:\Temp>python
    Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  6 2014, 22:16:31) [MSC
v.1600 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, subprocess
    >>> os.chdir(r'\\127.0.0.1\C$')
    >>> subprocess.call('cmd')
    Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

    (test) \\127.0.0.1\C$>

[1]: https://support.microsoft.com/en-us/kb/156276

From eryksun at gmail.com  Thu Apr 30 03:50:57 2015
From: eryksun at gmail.com (eryksun)
Date: Wed, 29 Apr 2015 20:50:57 -0500
Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths
In-Reply-To: <CACL+1asg31UUTSwXajGC7MrzPd6bDdmAoA5ej-K51q93pyeQuQ@mail.gmail.com>
References: <1430326451.93582.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
 <CACL+1asCGrw01Y3DO6qs9jTnWgqDWb-2ELtiU96p0FUyawbvSw@mail.gmail.com>
 <mhrrpa$jjo$1@ger.gmane.org>
 <CACL+1auqWH0NakimATPKYP-HSDPugCDvS25P3pX4fL4=LdvdyQ@mail.gmail.com>
 <CACL+1asg31UUTSwXajGC7MrzPd6bDdmAoA5ej-K51q93pyeQuQ@mail.gmail.com>
Message-ID: <CACL+1av8=Sp4iAQ1JeV_+J7dxF3x7L2mghbTZuaFcZwh5Rq=eA@mail.gmail.com>

On Wed, Apr 29, 2015 at 8:28 PM, eryksun <eryksun at gmail.com> wrote:
> After disabling the check, my previous example should work fine:

Except it doesn't accept paths relative to a UNC working directory:

    (test) \\127.0.0.1\C$>cd Temp
    The system cannot find the path specified.

And the cd command appears to ignore the registry setting:

    (test) \\127.0.0.1\C$>cd \\127.0.0.1\C$\Temp
    '\\127.0.0.1\C$\Temp'
    CMD does not support UNC paths as current directories.

Otherwise it works fine. ;-)

From cs at zip.com.au  Thu Apr 30 04:40:11 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Thu, 30 Apr 2015 12:40:11 +1000
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
 machine where Git cannot be installed?
In-Reply-To: <CANDiX9+K0fn1FEepYLJey8bw8OGhK6ABToafftNzqoE05ekSQQ@mail.gmail.com>
References: <CANDiX9+K0fn1FEepYLJey8bw8OGhK6ABToafftNzqoE05ekSQQ@mail.gmail.com>
Message-ID: <20150430024011.GA77453@cskk.homeip.net>

On 29Apr2015 12:12, boB Stepp <robertvstepp at gmail.com> wrote:
>> ... (3) install git if needed ...
>
>It seems Git is needed, but I am not allowed to install it on the
>Solaris workstation. So is there a way around this?

What do you mean by "install"? Bear in mind that while you may be forbidden 
from installing git in the main areas (/usr, /usr/local, whatever), you may be 
free to install it in your own home directory. It is just an executable...

Cheers,
Cameron Simpson <cs at zip.com.au>

From cs at zip.com.au  Thu Apr 30 04:09:22 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Thu, 30 Apr 2015 12:09:22 +1000
Subject: [Tutor] Fwd:  Function works one time then subsequently fails
In-Reply-To: <CALRAYNXBKSp-JoSHzKx2ONn3YZHuG8nJLGGPEDs9AgVSCyBNDQ@mail.gmail.com>
References: <CALRAYNXBKSp-JoSHzKx2ONn3YZHuG8nJLGGPEDs9AgVSCyBNDQ@mail.gmail.com>
Message-ID: <20150430020922.GA18991@cskk.homeip.net>

On 29Apr2015 08:34, Jim Mooney Py3.4.3winXP <cybervigilante at gmail.com> wrote:
>On 28 April 2015 at 22:40, Cameron Simpson <cs at zip.com.au> wrote:
>> We can pick over your code as well if you like. Should we?
>
>Sure, but let me include the full working program after fixup. Although I
>still have to write another program to feed it random problems to work it
>out. It's a bit spacey, but I ran it through the pep8 program and it
>suggested that. I think two spaces between such tiny functions is overkill,
>though.
>
>"""
>Takes the name of a binary math operation and two numbers from input,
>repeatedly, and displays the results until done
>"""
>
>def add(a, b):
>    return a + b
>
>
>def subtract(a, b):
>    return b - a
>
>
>def minus(a, b):
>    return a - b

These could all do with docstrings. add() is pretty obvious, but the 
distinction between minus() and subtract() could do with elaboration.

Also, I would be inclined to define minus() in terms of subtract(), not because 
it is faster but because it establishes an equivalence.

>def multiply(a, b):
>    return a * b
>
>
>def divide(a, b):
>    return a / b
>
>
>operations = {'add': add, '+': add, 'plus': add, 'subtract': subtract,
>'subtracted': subtract,
>              '-': minus, 'minus': minus, 'multiply': multiply, '*':
>multiply, 'multiplied': multiply,
>              'times': multiply, 'divide': divide, '/': divide, 'divided':
>divide}

I'd make this much more vertical, like this:

  operations = {'add': add,
                '+': add,
                'plus': add,
                'subtract': subtract,
                'subtracted': subtract,

Easier to maintain, easier to read, easier to modify, and if you use version 
control you will get much more meaningful diff output with changes, which aids 
code review (which more or less equates to readability and maintainability).

>def test_number(astring):
>    """
>    Input: A string that should represent a valid int or float. Output:
>    An int or float on success. None on failure.
>    """
>    for make_type in (int, float):
>        try:
>            return make_type(astring)
>        except ValueError:
>            pass
>    return None

If this is a test function, it should return True or False.

Other have already remarked on this in other threads: the Pythonic way to do 
this is usually to attempt the conversion and let an exception get out:

  def numberify(astring):
      return float(astring)

Consider the calling code. What are you going to do with it. I see you probe 
first, which makes some sense in lexical analysis:

>def parse_string(math_string):
>    """Input: A math string with a verbal or mathematical operation
>    and two valid numbers to operate on. Extra numbers and operations
>    are ignored. Output: A tuple containing a function corresponding
>    to the operation and the two numbers. Returns None on failure.
>    """
>    operation = None
>    tokens = math_string.split()
>    numbers = []
>    for token in tokens:
>        if token in operations:
>            operation = operations[token]
>        elif test_number(token) != None:
>            numbers.append(test_number(token))
>        if len(numbers) > 1:
>            break
>    if operation is None or len(numbers) < 2:
>        return None
>    else:
>        return operation, numbers[0], numbers[1]

As a lexical exercise probing (test then act) is pretty common and normal.  

However, an alternative way to structure this is the "ask for forgiveness" 
approach:

  try:
    operation = operations[token]
  except KeyError:
    value = numberify(token)
    numbers.append(value)

This will raise ValueError if it is neither an operation nor a number.

The practice of raising an exception permits a mode of programming where both 
your code and the caller can broadly write the code as though values are 
generally valid, and avoids a lot error catching verbiage that obscures the 
core logic.

In that vein, you would also modify the function to raise an exception 
(typically ValueError) for other invalid math_strings. The advantage here is 
that the caller can use your function like this:

  operation, *arguments = parse_string(math_string)

and not perform any special testing for getting None back. Instead, the caller 
can plow on as though the math_string was valid as well. An exception can 
bubble up to a suitable catch point, such as the main loop which reads strings 
from the user.

>instructions = '''Enter two numbers and one of the four basid math
>operations,
>either mathematical or verbal. i.e. 3 + 2, 12 divided by 14, 10 minus 4,
>etc.
>Enter done to quit.
>'''
>try:
>    user_input = input(instructions)
>    while True:
>        if user_input == 'done':
>            break

While most programs will accept a special token to exit, you can also just rely 
on seeing end of file. Most systems have a way of indicating this from the 
keyboard, often ^Z in Windows and ^D on UNIX terminals. So since input() is 
documented as raising EOFError in this circumstance you could add that to your 
catch below:

  except EOFError:
      print("End of input from user.")

Then, if parse_string() raises a ValueError in a Pythonic way you'd change:

>        result = parse_string(user_input)
>        if result == None:
>            print("Not a valid math operation.")
>        else:
>            func, num1, num2 = result
>            print(func(num1, num2))

into:

    try:
        operation, *arguments = parse_string(user_input)
    except ValueError as e:
        print("Invalid math operation: %s" % (e,))
    else:
        print(func(*arguments))

Notice that by returning the numeric parts into a list you can later implement 
operations with other numbers of arguments than 2.

>        user_input = input()

I would try to say that just once by putting it at the top of the loop, 
changing this:

    user_input = input(instructions)
    while True:

into:

    prompt = instructions
    while True:
        user_input = input(prompt)
        prompt = ''

thus calling input() from only one place. This also makes it easy to re-issue 
the instructions if the user offers invalid input by adding:

    prompt = instructions

to the "except" clause for a bad math string.

Finally, I might move main code into a main() function, which I would put at 
the _top_ of the program:

    def main():
        instructions = ......
        prompt = instructions
        while True:
            user_input = input(prompt)
            ..............

and at the bottom put this boilerplate:

    if __name__ == '__main__':
        main()

This final boilerplate is common in modules. When a python file is invoked 
directly the "module" name is "__main__". When the same python file is imported 
as a module, __name__ is the module name. This allows you to use the module as 
a main program in one circumstance and as a set of library functions when 
imported. The main program might be some primary function with code like yours 
or alternatively run various unit tests on the module functions if there is no 
natural "main program" to give the module.

Often I have both a legitimate main program and also unit tests. In that 
circumstance I usually give the "main program" a "test" mode, which will run 
the unit tests.

Cheers,
Cameron Simpson <cs at zip.com.au>

From robertvstepp at gmail.com  Thu Apr 30 05:10:02 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 29 Apr 2015 22:10:02 -0500
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
 machine where Git cannot be installed?
In-Reply-To: <20150430024011.GA77453@cskk.homeip.net>
References: <CANDiX9+K0fn1FEepYLJey8bw8OGhK6ABToafftNzqoE05ekSQQ@mail.gmail.com>
 <20150430024011.GA77453@cskk.homeip.net>
Message-ID: <CANDiX9+=jFBm+jFD2PO8mdXY19fEbiJ893e=LuSvP7LZOdTsHw@mail.gmail.com>

On Wed, Apr 29, 2015 at 9:40 PM, Cameron Simpson <cs at zip.com.au> wrote:
> On 29Apr2015 12:12, boB Stepp <robertvstepp at gmail.com> wrote:
>>>
>>> ... (3) install git if needed ...
>>
>>
>> It seems Git is needed, but I am not allowed to install it on the
>> Solaris workstation. So is there a way around this?
>
>
> What do you mean by "install"? Bear in mind that while you may be forbidden
> from installing git in the main areas (/usr, /usr/local, whatever), you may
> be free to install it in your own home directory. It is just an
> executable...

On the smart enterprise where we (now) do our clinical planning they
are very strict: no installing any external software; no accessing the
Internet; no email; etc. Not all centers adhere to this level of
strictness, but ours does. To be honest, I am surprised they allow me
to do the programming I do, but so far it has been all pluses and no
minuses, and for those dosimetrists who choose to use the tools I have
developed, they are more productive than they would be doing things by
hand.

Now the 810X Solaris workstation that was retired when we went to
smart enterprise is *mine* and they really don't care anymore what I
do with it. When it was being used for actual clinical planning, it
had its Internet access disabled, etc. I have since restored it, so I
could install software now, including Git. But I am reluctant to do
anything that I am not allowed to replicate on smart enterprise. I am
trying to keep it as close to identical to the actual clinical
environment as I can. Perhaps this is misguided on my part? As always,
I welcome your thoughts. It could be I am being unnecessarily cautious
in regards to the 810X, but as has been pointed out there is much I do
not know, so my motto is to first ensure I do no harm...

-- 
boB

From davea at davea.name  Thu Apr 30 05:43:34 2015
From: davea at davea.name (Dave Angel)
Date: Wed, 29 Apr 2015 23:43:34 -0400
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <CAMxbqSM9R=-wXb-Ah6fErw0Z_tQTO0RxBGSUzd8tY0mz93yOgA@mail.gmail.com>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
 <mhq2c2$pr$1@ger.gmane.org>
 <CAMxbqSP51m7O45RwnSM1VY0MnCXH8majshwfC=_md7-YxP07XQ@mail.gmail.com>
 <554095BF.2000208@btinternet.com>
 <CAMxbqSOv+jTT0brUL1ny_irBMBsDzASS4cSqrqLtVJcjaUyO8w@mail.gmail.com>
 <mhr0v6$8cs$1@ger.gmane.org>
 <CAMxbqSM9R=-wXb-Ah6fErw0Z_tQTO0RxBGSUzd8tY0mz93yOgA@mail.gmail.com>
Message-ID: <5541A4E6.3020209@davea.name>

On 04/29/2015 02:37 PM, diliup gabadamudalige wrote:
> I do not understand how Alan does not get the code that is in this thread.

There are at least 3 ways of posting to "this thread":
    A) email
    B) newsgroup
    C) googlegroups

and at least 5 ways of looking at "this thread"
    A) email
    B) email digest
    C) newsgroup
    D) googlegroups
    E) various archives

To get messages from one region to another involves going through a 
gateway, and most of them damage some of the messages going through.  To 
minimize the likelihood that what looks good on your screen will be 
missing or different on mine or on Alan's, follow a few rules:

    1) avoid html
    2) avoid attachments

There are others, but those seem to be the biggies.

Many other guidelines will help readability and consistency, like not 
top-posting, using proper quoting and attribution, giving enough 
information but not too much, specifying the whole environment in the 
FIRST message of a thread, etc.

-- 
DaveA

From robertvstepp at gmail.com  Thu Apr 30 05:49:46 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 29 Apr 2015 22:49:46 -0500
Subject: [Tutor] Is there a way to store and later use comparison
 operators (<, <=, =, >=, >) ?
In-Reply-To: <mhrj8i$bu1$1@ger.gmane.org>
References: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
 <mhrj8i$bu1$1@ger.gmane.org>
Message-ID: <CANDiX9L+Br9gsPQwmp+1VLfup90ETGYPg8S_w0Px5TL2ipsj0Q@mail.gmail.com>

On Wed, Apr 29, 2015 at 4:42 PM, Mark Lawrence <breamoreboy at yahoo.co.uk> wrote:

> This isn't a job for Bicycle Repair Man!!!

<chuckle!> Not even if we only use the latest, greatest,
computer-aided bicycle repair technology???

> ... It smacks to me of dictionaries
> and the operator module but I'm too bone idle to look it up myself, so try
> here https://docs.python.org/3/library/operator.html
> D'oh :)

So little time, so much Python standard library! I *do* search and
search and ... search before I ask, but my Google-fu is often weak,
especially when I am searching for hints as to how to solve a problem
where I am unsure of the correct technical terminology to use in the
search. OTH, I have sometimes spent hours searching, both online and
in what books I have, and thus spared y'all many, ... , many other
questions that I might have otherwise asked!

One problem I have with searching the Python documentation is this:
https://docs.python.org/release/2.4.4/lib/lib.html
I never would have guessed beforehand that I would be needing to look
under: "3. Python Runtime Services! I spend most of my time on this
page as this is my most limiting version of Python that I must deal
with.

This page is *not* well-formatted and it all runs together. Even when
I *know* something is there, I find myself having to Ctrl-F and
entering the term I am looking for. And when I am not sure what I am
looking for, I don't usually come up with the correct term. The later
Python docs are much easier on the eyes, I do say!

Anyway, Mark, thanks for the link! This looks quite straightforward
and I will be able to side-step the evils of eval() once again.

-- 
boB

From robertvstepp at gmail.com  Thu Apr 30 05:57:26 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 29 Apr 2015 22:57:26 -0500
Subject: [Tutor] Is there a way to store and later use comparison
 operators (<, <=, =, >=, >) ?
In-Reply-To: <mhrn58$cfc$1@ger.gmane.org>
References: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
 <CAKK8jXagTTzw-E9Y6yxsCUOCQAvQU0hU9CcMQDG-WrTf+Y4hRA@mail.gmail.com>
 <CANDiX9LDy2zZHtXqa_RGUO5r+wHF0kJLFnGACxfLJv3QDV=NMQ@mail.gmail.com>
 <mhrn58$cfc$1@ger.gmane.org>
Message-ID: <CANDiX9+zOY4YWWX_qxONmupWJYoYSZ7M9x05FvCcC1Ad52wQRw@mail.gmail.com>

On Wed, Apr 29, 2015 at 5:49 PM, Peter Otten <__peter__ at web.de> wrote:
> boB Stepp wrote:

>> So I have stumbled (With your gracious help!) into a legitimate use of
>> eval()?
>
> No. To expand on Marks hint here's how to do it without evil eval().
>
> import operator
>
> comps = {
>     "=": operator.eq,
>     "<": operator.lt,
>     ">": operator.gt,
>     # ...
> }
>
> def choose_compare(operator, value0, value1, pass_color, fail_color):
>     op = comps[operator]
>     if op(value0, value1):
>         return pass_color, True
>     else:
>         return fail_color, False
>
> print(choose_compare("=", 1, 1, "red", "blue"))
> print(choose_compare("<", 1, 2, "red", "blue"))
> print(choose_compare("<", 2, 1, "red", "blue"))
>
> Rule of thumb: when you think you need eval() you're wrong.

Thanks, Peter! The lure of eval() once more avoided...


-- 
boB

From cs at zip.com.au  Thu Apr 30 05:39:25 2015
From: cs at zip.com.au (Cameron Simpson)
Date: Thu, 30 Apr 2015 13:39:25 +1000
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
 machine where Git cannot be installed?
In-Reply-To: <CANDiX9+=jFBm+jFD2PO8mdXY19fEbiJ893e=LuSvP7LZOdTsHw@mail.gmail.com>
References: <CANDiX9+=jFBm+jFD2PO8mdXY19fEbiJ893e=LuSvP7LZOdTsHw@mail.gmail.com>
Message-ID: <20150430033925.GA10288@cskk.homeip.net>

On 29Apr2015 22:10, boB Stepp <robertvstepp at gmail.com> wrote:
>On Wed, Apr 29, 2015 at 9:40 PM, Cameron Simpson <cs at zip.com.au> wrote:
>> On 29Apr2015 12:12, boB Stepp <robertvstepp at gmail.com> wrote:
>>>> ... (3) install git if needed ...
>>>
>>> It seems Git is needed, but I am not allowed to install it on the
>>> Solaris workstation. So is there a way around this?
>>
>> What do you mean by "install"? Bear in mind that while you may be forbidden
>> from installing git in the main areas (/usr, /usr/local, whatever), you may
>> be free to install it in your own home directory. It is just an
>> executable...
>
>On the smart enterprise where we (now) do our clinical planning they
>are very strict: no installing any external software; no accessing the
>Internet; no email; etc. Not all centers adhere to this level of
>strictness, but ours does. [...] But I am reluctant to do
>anything that I am not allowed to replicate on smart enterprise. I am
>trying to keep it as close to identical to the actual clinical
>environment as I can.

And fair enough too. I frequently wish our developers' dev environments more 
rigorously modelled the target environment.

>Perhaps this is misguided on my part?

Not necessarily.

But I would be inclined to distinguish your working tools from the target 
environment.

For example, I commend you making your dev environment as close to identical to 
the actual clinical environment as you can. But I wouldn't deprive yourself of 
tools that enhance your code management practices without affecting that 
environment.

For example, there is much to be said for tracking your changes with a tool 
like git or hg. It encourages your to annotate your changes, and lets you 
review history to see when and why some change occurred, especially if a new 
bug has arisen. Distributed version control systems like git and hg also make 
it easier to work on distinct changes to the same code as separate work 
processes; of course the price for such a workflow is that you need to merge 
the two things later and ensure that they do not interact badly.

If you're serious about keeping the two environments very similar, you could 
always do your _coding_ on a third platform (a laptop or whatever) using your 
desired tools and _deploy_ the code to the dev (and later, prod) environments 
from there, keeping the dev environment pristine. By "deploy", that can be as 
simple as copying the code to the target.

Just thoughts; of course you must choose practices that suit your needs and 
plans.

Cheers,
Cameron Simpson <cs at zip.com.au>

Nothing is impossible for the man who doesn't have to do it.

From davea at davea.name  Thu Apr 30 06:14:57 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 30 Apr 2015 00:14:57 -0400
Subject: [Tutor] raise exception works as planned in program but not
 when imported into testing module
In-Reply-To: <CALRAYNUAdy8NkUQuWyoq-e+y3NMaU06di5pf6gNNo6ddZFbfew@mail.gmail.com>
References: <CALRAYNUAdy8NkUQuWyoq-e+y3NMaU06di5pf6gNNo6ddZFbfew@mail.gmail.com>
Message-ID: <5541AC41.9010702@davea.name>

On 04/29/2015 09:05 PM, Jim Mooney Py3.4.3winXP wrote:
> I raised an exception in the parse_string function in my math parser
> program, function_tosser.py, and caught it in the calling routine, and that
> worked fine. But when I imported function_tosser.py into a test program,
> tester.py, it threw the exception in the parse_string function instead of
> handling it in the try block in the calling routine. Why did it work in one
> and not the other? The testing program works fine if I return None as I did
> before, instead of raising the exception.

It'd be nice if you were explicit about which code you're describing.  I 
can make guesses, but your above paragraph leaves a lot of confusion.

I'm guessing you're talking about the line in parse_string():
         raise ValueError

And I assume you're talking about it being referenced in the other file 
by the line:
         print(ft.parse_string(monkey_wrench), '\n')

But why are you surprised?  There's no try/except protecting the latter 
line, so the exception will be uncaught, and you'll see it reported in 
parse_string().

 > in the try block in the calling routine.

What routine is that?  The line I quoted above is in top-level code, not 
in a routine. And it doesn't have a try/except there.

>
> # function_tosser.py
> """
> Takes the name of a binary math operation and two numbers from input,
> repeatedly, and displays the results until done
> """
>
>
> def add(a, b):
>      return a + b
>
>
> def subtract(a, b):
>      return b - a
>
> def minus(a, b):
>      return a - b
>
>
> def multiply(a, b):
>      return a * b
>
>
> def divide(a, b):
>      return a / b
>
>
> operations = {'add': add, '+': add, 'plus': add, 'subtract': subtract,
> 'subtracted': subtract,
>                '-': minus, 'minus': minus, 'multiply': multiply, '*':
> multiply, 'multiplied': multiply,
>                'times': multiply, 'divide': divide, '/': divide, 'divided':
> divide}
>
> def test_number(astring):
>      """
>      Input: A string that should represent a valid int or float. Output:
>      An int or float on success. None on failure.
>      """
>      for make_type in (int, float):
>          try:
>              return make_type(astring)
>          except ValueError: # Previously returned None, which worked. This
> works fine here but when imported into the test program
>              pass           # it doesn't wait for the try block in the
> calling routine.
>      return None
>
>
> def parse_string(math_string):
>      """Input: A math string with a verbal or mathematical operation
>      and two valid numbers to operate on. Extra numbers and operations
>      are ignored. Output: A tuple containing a function corresponding
>      to the operation and the two numbers. Returns None on failure.
>      """
>      operation = None
>      tokens = math_string.split()
>      numbers = []
>      for token in tokens:
>          if token in operations:
>              operation = operations[token]
>          elif test_number(token) != None:
>              numbers.append(test_number(token))
>          if len(numbers) > 1:
>              break
>      if operation is None or len(numbers) < 2:
>          raise ValueError
>      else:
>          return operation, numbers[0], numbers[1]
>
> if __name__ == "__main__":
>      instructions = '''Enter two numbers and one of the four basid math
> operations,
>      either mathematical or verbal. i.e. 3 + 2, 12 divided by 14, 10 minus
> 4, etc.
>      Enter done to quit.
>      '''
>      try:
>          user_input = input(instructions)
>          while True:
>              if user_input == 'done':
>                  break
>              try:
>                  result = parse_string(user_input)
>              except ValueError:
>                  print("Not a valid math operation.")
>              else:
>                  func, num1, num2 = result
>                  print(func(num1, num2))
>              user_input = input()
>      except KeyboardInterrupt:
>          print("Program terminated by user")
>
> # tester.py
>
> '''Test function_tosser.py mainlogic against random operators, operands,
> and bad input'''
> import random
> import function_tosser as ft
> valid_terms = list(ft.operations.keys())
> def eval_test():
>      pass
>
> trash = ['1 +', 'blah', '3-4', 'gargle', 'Newt Gingrich',
>      ",,,,,", '{+=-33.44 minus12 3 times blarg 1445641654644555455']
>
> for ctr in range(50):
>      term = ' ' + random.choice(valid_terms) + ' '
>      num1 = str(random.randint(1,1000))
>      num2 = str(random.randint(1,1000))
>      if term == ' subtract ' or term == ' subtracted ': term = ' subtracted
> from '
>      if ctr % 10 == 0: # stress testing for a None failure
>          monkey_wrench = random.choice(trash)
>          print(ft.parse_string(monkey_wrench), '\n')
>      else:
>          func, num1, num2 = ft.parse_string(num1 + term + num2)
>          print(func, num1, term, num2)
>          print('result:',func(num1, num2), '\n')
>
>


-- 
DaveA

From robertvstepp at gmail.com  Thu Apr 30 06:28:59 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Wed, 29 Apr 2015 23:28:59 -0500
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
 machine where Git cannot be installed?
In-Reply-To: <20150430033925.GA10288@cskk.homeip.net>
References: <CANDiX9+=jFBm+jFD2PO8mdXY19fEbiJ893e=LuSvP7LZOdTsHw@mail.gmail.com>
 <20150430033925.GA10288@cskk.homeip.net>
Message-ID: <CANDiX9LCQpsJkfowQp-uovqH89aXnPaMjE14tCRrBPyV54B5SQ@mail.gmail.com>

On Wed, Apr 29, 2015 at 10:39 PM, Cameron Simpson <cs at zip.com.au> wrote:
> On 29Apr2015 22:10, boB Stepp <robertvstepp at gmail.com> wrote:

>> On the smart enterprise where we (now) do our clinical planning they
>> are very strict: no installing any external software; no accessing the
>> Internet; no email; etc. Not all centers adhere to this level of
>> strictness, but ours does. [...] But I am reluctant to do
>> anything that I am not allowed to replicate on smart enterprise. I am
>> trying to keep it as close to identical to the actual clinical
>> environment as I can.
>
>
> And fair enough too. I frequently wish our developers' dev environments more
> rigorously modelled the target environment.
>
>> Perhaps this is misguided on my part?
>
>
> Not necessarily.
>
> But I would be inclined to distinguish your working tools from the target
> environment.
>
> For example, I commend you making your dev environment as close to identical
> to the actual clinical environment as you can. But I wouldn't deprive
> yourself of tools that enhance your code management practices without
> affecting that environment.
>
> For example, there is much to be said for tracking your changes with a tool
> like git or hg. It encourages your to annotate your changes, and lets you
> review history to see when and why some change occurred, especially if a new
> bug has arisen. Distributed version control systems like git and hg also
> make it easier to work on distinct changes to the same code as separate work
> processes; of course the price for such a workflow is that you need to merge
> the two things later and ensure that they do not interact badly.

Totally, totally convinced of the correctness of this. Actively
working to implement this. See below.

> If you're serious about keeping the two environments very similar, you could
> always do your _coding_ on a third platform (a laptop or whatever) using
> your desired tools and _deploy_ the code to the dev (and later, prod)
> environments from there, keeping the dev environment pristine. By "deploy",
> that can be as simple as copying the code to the target.

That is what I have implemented as of today. I installed Git on my
Windows PC where I have been doing my actual coding anyway, created
the needed repositories, including an extra one on our intranet in
case my PC dies, etc. The current project is now in version control.
After doing some editing and saving, I use the Git bash shell that
came with Git and scp the file(s) to the dev environment, do my
testing (Still manual; working on getting automated, but this will
have more of a learning curve for me than using Git.), etc. When I get
a meaningful chunk of something done, I add and commit in Git on the
Windows PC. Less often I push to the intranet repo. Your comments
suggest that I am on a reasonable track.

The main danger as I see it is that if I am not careful, then the code
on the dev environment could diverge from the state of code on my
Windows PC, i.e., I forgot to do the scp part. But when I am actively
working on a section of code I always insert a few print statements
(Py 2.4!) to verify I am getting what I should when I test it
out--even if I don't have an actual problem yet. And so far this has
immediately revealed those few instances so far when I forgot to save
to the dev machine (Usually when someone has interrupted my workflow,
a near constant occurrence at work.).


-- 
boB

From davea at davea.name  Thu Apr 30 06:38:21 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 30 Apr 2015 00:38:21 -0400
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
 machine where Git cannot be installed?
In-Reply-To: <CANDiX9LCQpsJkfowQp-uovqH89aXnPaMjE14tCRrBPyV54B5SQ@mail.gmail.com>
References: <CANDiX9+=jFBm+jFD2PO8mdXY19fEbiJ893e=LuSvP7LZOdTsHw@mail.gmail.com>
 <20150430033925.GA10288@cskk.homeip.net>
 <CANDiX9LCQpsJkfowQp-uovqH89aXnPaMjE14tCRrBPyV54B5SQ@mail.gmail.com>
Message-ID: <5541B1BD.6030600@davea.name>

On 04/30/2015 12:28 AM, boB Stepp wrote:
> The main danger as I see it is that if I am not careful, then the code
> on the dev environment could diverge from the state of code on my
> Windows PC, i.e., I forgot to do the scp part. But when I am actively
> working on a section of code I always insert a few print statements
> (Py 2.4!) to verify I am getting what I should when I test it
> out--even if I don't have an actual problem yet. And so far this has
> immediately revealed those few instances so far when I forgot to save
> to the dev machine (Usually when someone has interrupted my workflow,
> a near constant occurrence at work.).
>
>

Add an automatic file copy to the save-key definition in your editor. 
Then whenever you save the file locally, you'll also be copying it to 
the master location.

If that's too hard, or your editor can't support it, write a bash script 
that does an rsynch every 10 minutes.

rsynch does what scp does, but it works on whole directories, copying 
only those files that changed.  And you can fine tune what "changed" means.

There are other, less resource intense approaches, but if one of these 
works, it'll be pretty painless to set up.

-- 
DaveA

From ben+python at benfinney.id.au  Thu Apr 30 07:15:26 2015
From: ben+python at benfinney.id.au (Ben Finney)
Date: Thu, 30 Apr 2015 15:15:26 +1000
Subject: [Tutor] Ancient Python versions (was: Is there a way to store and
	later use comparison operators (<, <=, =, >=, >) ?)
References: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
 <mhrj8i$bu1$1@ger.gmane.org>
 <CANDiX9L+Br9gsPQwmp+1VLfup90ETGYPg8S_w0Px5TL2ipsj0Q@mail.gmail.com>
Message-ID: <85lhhai4cx.fsf_-_@benfinney.id.au>

boB Stepp <robertvstepp at gmail.com> writes:

> One problem I have with searching the Python documentation is this:
> https://docs.python.org/release/2.4.4/lib/lib.html

If you actually need to read the documentation specifically for a Python
version that has not been supported since 2008, then I agree that is a
problem.

The documentation has improved since then. If you want newer-looking
documentation, maybe you should not expect it from a Python released
nearlt a decade ago?

-- 
 \     ?Not to be absolutely certain is, I think, one of the essential |
  `\                         things in rationality.? ?Bertrand Russell |
_o__)                                                                  |
Ben Finney


From cybervigilante at gmail.com  Thu Apr 30 08:04:16 2015
From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP)
Date: Wed, 29 Apr 2015 23:04:16 -0700
Subject: [Tutor] raise exception works as planned in program but not
 when imported into testing module
In-Reply-To: <5541AC41.9010702@davea.name>
References: <CALRAYNUAdy8NkUQuWyoq-e+y3NMaU06di5pf6gNNo6ddZFbfew@mail.gmail.com>
 <5541AC41.9010702@davea.name>
Message-ID: <CALRAYNV27ZAan36NTWQ+77v_tQkJHsHcf2-Auu8gPbDHVXRpHQ@mail.gmail.com>

On 29 April 2015 at 21:14, Dave Angel <davea at davea.name> wrote:

> But why are you surprised?  There's no try/except protecting the latter
> line, so the exception will be uncaught, and you'll see it reported in
> parse_string().
>

I think I meant something like this. An exception in a function is caught
by the caller. I imported the program that did this into the test program,
expecting the exception to still be caught when the parse_string was
called, by the try except else block in the mainroutine of the imported
program..

def excepter():
    raise ValueError

try:
    excepter()
except ValueError:
    print("Exception caught after function call")

REPL
>>>
Exception caught after function call
>>>


-- 
Jim

"What a rotten, failed experiment. I'll start over. Maybe dogs instead of
monkeys this time." --God

From cybervigilante at gmail.com  Thu Apr 30 08:16:12 2015
From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP)
Date: Wed, 29 Apr 2015 23:16:12 -0700
Subject: [Tutor] Fwd: Function works one time then subsequently fails
In-Reply-To: <20150430020922.GA18991@cskk.homeip.net>
References: <CALRAYNXBKSp-JoSHzKx2ONn3YZHuG8nJLGGPEDs9AgVSCyBNDQ@mail.gmail.com>
 <20150430020922.GA18991@cskk.homeip.net>
Message-ID: <CALRAYNWDLGpVPcoPuzKOtQsp-MKtMkQU+OfPqBi8hj_MZp4DrA@mail.gmail.com>

Sure, but let me include the full working program after fixup....

On 29 April 2015 at 19:09, Cameron Simpson <cs at zip.com.au> wrote:

>
> These could all do with docstrings. add() is pretty obvious, but the
> distinction between minus() and subtract() could do with elaboration.

etc, etc.

Thanks. Very comprehensive. I'll print it out and ponder it ;')

-- 
Jim

"What a rotten, failed experiment. I'll start over. Maybe dogs instead of
monkeys this time." --God

From cybervigilante at gmail.com  Thu Apr 30 09:08:04 2015
From: cybervigilante at gmail.com (Jim Mooney Py3.4.3winXP)
Date: Thu, 30 Apr 2015 00:08:04 -0700
Subject: [Tutor] raise exception works as planned in program but not
 when imported into testing module
In-Reply-To: <CALRAYNV27ZAan36NTWQ+77v_tQkJHsHcf2-Auu8gPbDHVXRpHQ@mail.gmail.com>
References: <CALRAYNUAdy8NkUQuWyoq-e+y3NMaU06di5pf6gNNo6ddZFbfew@mail.gmail.com>
 <5541AC41.9010702@davea.name>
 <CALRAYNV27ZAan36NTWQ+77v_tQkJHsHcf2-Auu8gPbDHVXRpHQ@mail.gmail.com>
Message-ID: <CALRAYNXD80u2OYb2La32ws7x8qcbgPvd5rSMayVnU=MRHiHDAw@mail.gmail.com>

Oops, my mistake. Ignore dumb remark below.  I was thinking of the try -
except in the main loop, but since I only tested the parse function, I
never used that. I need to look a bit harder and find this stuff Before I
post ;')

Jim

On 29 April 2015 at 23:04, Jim Mooney Py3.4.3winXP <cybervigilante at gmail.com
> wrote:

>
> I think I meant something like this. An exception in a function is caught
> by the caller. I imported the program that did this into the test program,
> expecting the exception to still be caught when the parse_string was
> called, by the try except else block in the mainroutine of the imported
> program..
>
> def excepter():
>     raise ValueError
>
> try:
>     excepter()
> except ValueError:
>     print("Exception caught after function call")
>
> REPL
> >>>
> Exception caught after function call
>




-- 
Jim

"What a rotten, failed experiment. I'll start over. Maybe dogs instead of
monkeys this time." --God

From braveart08 at yahoo.com.au  Thu Apr 30 05:58:25 2015
From: braveart08 at yahoo.com.au (Jag Sherrington)
Date: Thu, 30 Apr 2015 03:58:25 +0000 (UTC)
Subject: [Tutor] Newbie problems
Message-ID: <465451395.1213571.1430366305635.JavaMail.yahoo@mail.yahoo.com>

Can anyone please tell me what I am doing wrong?As this code I have for the Roulette Wheel colours exercise, won't work.?number = int(input('Enter a number between 0 and 36: '))green_number = (0)?red_number = (1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36)?black_number = (2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 34, 29, 31, 33, 35)
if number == green_number:? ? print('Number is Green')? ??elif number == red_number:? ? print('Number is Red')? ??elif number == black_number:? ? ? ? print('Number is Black')
Thank you for any help, Jag


From diliupg at gmail.com  Thu Apr 30 08:57:57 2015
From: diliupg at gmail.com (diliup gabadamudalige)
Date: Thu, 30 Apr 2015 12:27:57 +0530
Subject: [Tutor] Fwd: circular movement in pygame
In-Reply-To: <5541A4E6.3020209@davea.name>
References: <CAMxbqSPVuwbvbP3VxweDLtZ2NJjbvEgUmuswGxAgM3aovGLrqA@mail.gmail.com>
 <CAMxbqSNmUou8eKU49fcY4auV0hKrcdJLjS98af2C5KgjyWivWQ@mail.gmail.com>
 <CAHVvXxRBjDHD0fV5=NhjSaucE=XykyvHoPWPj0KL5W8SWxDdUg@mail.gmail.com>
 <CAMxbqSOPBzTSSvXi1mxTUFmTcRAJKAqwLz80ZLwviN34ZhgUtA@mail.gmail.com>
 <554014CA.90601@davea.name>
 <CAMxbqSPg8ZJQxL=0Fja_46XebyNoWokPYgS=HCwDQK-KA7e4Nw@mail.gmail.com>
 <mhq2c2$pr$1@ger.gmane.org>
 <CAMxbqSP51m7O45RwnSM1VY0MnCXH8majshwfC=_md7-YxP07XQ@mail.gmail.com>
 <554095BF.2000208@btinternet.com>
 <CAMxbqSOv+jTT0brUL1ny_irBMBsDzASS4cSqrqLtVJcjaUyO8w@mail.gmail.com>
 <mhr0v6$8cs$1@ger.gmane.org>
 <CAMxbqSM9R=-wXb-Ah6fErw0Z_tQTO0RxBGSUzd8tY0mz93yOgA@mail.gmail.com>
 <5541A4E6.3020209@davea.name>
Message-ID: <CAMxbqSMrEO7X2WdBmXShej0A=beXOmtiQUxet8z9iNH=MtdjvA@mail.gmail.com>

Thanks all for the very informative responses especially to Alan for being
descriptive.

I am now going to make my movement linear and move away from my current
circular one.

I hope a little bit of fun and "Thank you" emails fall into the order of
the day..

:)

On Thu, Apr 30, 2015 at 9:13 AM, Dave Angel <davea at davea.name> wrote:

> On 04/29/2015 02:37 PM, diliup gabadamudalige wrote:
>
>> I do not understand how Alan does not get the code that is in this thread.
>>
>
> There are at least 3 ways of posting to "this thread":
>    A) email
>    B) newsgroup
>    C) googlegroups
>
> and at least 5 ways of looking at "this thread"
>    A) email
>    B) email digest
>    C) newsgroup
>    D) googlegroups
>    E) various archives
>
> To get messages from one region to another involves going through a
> gateway, and most of them damage some of the messages going through.  To
> minimize the likelihood that what looks good on your screen will be missing
> or different on mine or on Alan's, follow a few rules:
>
>    1) avoid html
>    2) avoid attachments
>
> There are others, but those seem to be the biggies.
>
> Many other guidelines will help readability and consistency, like not
> top-posting, using proper quoting and attribution, giving enough
> information but not too much, specifying the whole environment in the FIRST
> message of a thread, etc.
>
> --
> DaveA
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Diliup Gabadamudalige

http://www.diliupg.com
http://soft.diliupg.com/

**********************************************************************************************
This e-mail is confidential. It may also be legally privileged. If you are
not the intended recipient or have received it in error, please delete it
and all copies from your system and notify the sender immediately by return
e-mail. Any unauthorized reading, reproducing, printing or further
dissemination of this e-mail or its contents is strictly prohibited and may
be unlawful. Internet communications cannot be guaranteed to be timely,
secure, error or virus-free. The sender does not accept liability for any
errors or omissions.
**********************************************************************************************

From lac at openend.se  Thu Apr 30 08:02:33 2015
From: lac at openend.se (Laura Creighton)
Date: Thu, 30 Apr 2015 08:02:33 +0200
Subject: [Tutor] Python 2.4 (was comparison operators)
In-Reply-To: Message from boB Stepp <robertvstepp@gmail.com> of "Wed,
 29 Apr 2015 22:49:46 -0500."
 <CANDiX9L+Br9gsPQwmp+1VLfup90ETGYPg8S_w0Px5TL2ipsj0Q@mail.gmail.com>
References: <CANDiX9JNb6z9s9mYbXvcj63FF9kqNuNsjqHdtheMEFckCQxL6Q@mail.gmail.com>
 <mhrj8i$bu1$1@ger.gmane.org><CANDiX9L+Br9gsPQwmp+1VLfup90ETGYPg8S_w0Px5TL2ipsj0Q@mail.gmail.com>
Message-ID: <201504300602.t3U62XvL010296@fido.openend.se>

Python 2.4 is really old, right now.  OpenCSW has 2.6.9
http://www.opencsw.org/package/python/

Any chance you could use that?

Laura


From lac at openend.se  Thu Apr 30 08:12:55 2015
From: lac at openend.se (Laura Creighton)
Date: Thu, 30 Apr 2015 08:12:55 +0200
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
	machine where Git cannot be installed?
In-Reply-To: Message from boB Stepp <robertvstepp@gmail.com> of "Wed,
 29 Apr 2015 23:28:59 -0500."
 <CANDiX9LCQpsJkfowQp-uovqH89aXnPaMjE14tCRrBPyV54B5SQ@mail.gmail.com>
References: <CANDiX9+=jFBm+jFD2PO8mdXY19fEbiJ893e=LuSvP7LZOdTsHw@mail.gmail.com>
 <20150430033925.GA10288@cskk.homeip.net><CANDiX9LCQpsJkfowQp-uovqH89aXnPaMjE14tCRrBPyV54B5SQ@mail.gmail.com>
Message-ID: <201504300612.t3U6Ct3Y010718@fido.openend.se>

In a message of Wed, 29 Apr 2015 23:28:59 -0500, boB Stepp writes:

>The main danger as I see it is that if I am not careful, then the code
>on the dev environment could diverge from the state of code on my
>Windows PC, i.e., I forgot to do the scp part. But when I am actively
>working on a section of code I always insert a few print statements
>(Py 2.4!) to verify I am getting what I should when I test it
>out--even if I don't have an actual problem yet. And so far this has
>immediately revealed those few instances so far when I forgot to save
>to the dev machine (Usually when someone has interrupted my workflow,
>a near constant occurrence at work.).

If you can get git running on your solaris development machine, you can
get out of the 'manually copying files' business. You can just ask git
for an up to date version of all your code, all your tests, all your
documentation -- all the files. :)

From smarugg at gmail.com  Thu Apr 30 04:59:48 2015
From: smarugg at gmail.com (Spencer For Friends)
Date: Wed, 29 Apr 2015 22:59:48 -0400
Subject: [Tutor] if/then statement and sql count rows
Message-ID: <CAAAQYPcgjRW2o8BNU_7ewiS=i=_-Pdv3LOK5f1oAjFw=dPAY2g@mail.gmail.com>

Hi All,

I'm attempting to perform an if then statement based on the results of a
sql count rows query. The query is returning the proper values however the
if/then statement seems to be ignoring the returned value of the sql
statement.

Here is my code.

    import sqlite3

    # Define SQL statement to select all Data from Column Name
    sql = "SELECT Count(*) FROM arbtable WHERE Name = ?"

    book_name = 'Winged Coat'

    class PriceCheck(object):
        def __init__(self, db):
            self.conn = sqlite3.connect(db)
            self.c = self.conn.cursor()


        def query(self, arg, cardname):
            self.c.execute(arg, cardname)
            return self.c

        def __del__(self):
            self.conn.close()

    def display():
    #Connect To DB and Get Price of Matched book.
        getbookprice = PriceCheck("arbbase.sqlite")
        for row in getbookprice.query(sql, ([book_name])):
            if row == 0:
                print 'no row was found'
            else:
               print 'Yep its there!'
                print row



    display()

The program here is that my result, as evidenced by "print row" at the
bottom of the code is 0. Since it is zero according to my if statement it
should print 'no row was found', but instead it prints the else statement
value of 'yes its there!'

I've researched extensively and think that possibly the fetchone statement
is what I need, but I can't seem to figure out how to properly apply this
to my code to test it.

Any help would be highly appreciated.

Thank you kindly

Sour Jack

From alan.gauld at btinternet.com  Thu Apr 30 10:15:07 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 30 Apr 2015 09:15:07 +0100
Subject: [Tutor] subprocess.Popen(..., cwd) and UNC paths
In-Reply-To: <CACL+1auqWH0NakimATPKYP-HSDPugCDvS25P3pX4fL4=LdvdyQ@mail.gmail.com>
References: <1430326451.93582.BPMail_high_carrier@web163803.mail.gq1.yahoo.com>
 <CACL+1asCGrw01Y3DO6qs9jTnWgqDWb-2ELtiU96p0FUyawbvSw@mail.gmail.com>
 <mhrrpa$jjo$1@ger.gmane.org>
 <CACL+1auqWH0NakimATPKYP-HSDPugCDvS25P3pX4fL4=LdvdyQ@mail.gmail.com>
Message-ID: <5541E48B.6070807@btinternet.com>

On 30/04/15 01:48, eryksun wrote:
> > Actually cmd.exe is fine with UNC paths.
> cmd.exe cannot use a UNC path as the current directory.
Oops, my mistake. I got my POSIX and UNC mixed up.
I was thinking about forward slashes etc not network names.

Apologies for not reading the message properly.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


From davea at davea.name  Thu Apr 30 10:27:30 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 30 Apr 2015 04:27:30 -0400
Subject: [Tutor] Newbie problems
In-Reply-To: <465451395.1213571.1430366305635.JavaMail.yahoo@mail.yahoo.com>
References: <465451395.1213571.1430366305635.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <5541E772.4020906@davea.name>

On 04/29/2015 11:58 PM, Jag Sherrington wrote:
> Can anyone please tell me what I am doing wrong?As this code I have for the Roulette Wheel colours exercise, won't work. number = int(input('Enter a number between 0 and 36: '))green_number = (0) red_number = (1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36) black_number = (2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 34, 29, 31, 33, 35)
> if number == green_number:    print('Number is Green')    elif number == red_number:    print('Number is Red')    elif number == black_number:        print('Number is Black')
> Thank you for any help, Jag
>

Please post your code the way you're going to run it, like one statement 
per line, indented as required, etc.

Your problem is you're comparing an int (number) to a list (green_number 
or red_number or black_number).  They'll never be equal so it won't 
print anything.

presumably you don't want to know if the number is equal to the list, 
but whether it's in the list.  The "in" operator will tell you that.

Something like:
     if number in green_numbers:

(I changed it to plural, so it'd be more obvious that it's not a single 
value, but a list of them.  Little things like that can make errors much 
easier to spot.)


-- 
DaveA

From alan.gauld at btinternet.com  Thu Apr 30 10:28:07 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 30 Apr 2015 09:28:07 +0100
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
 machine where Git cannot be installed?
In-Reply-To: <CANDiX9LCQpsJkfowQp-uovqH89aXnPaMjE14tCRrBPyV54B5SQ@mail.gmail.com>
References: <CANDiX9+=jFBm+jFD2PO8mdXY19fEbiJ893e=LuSvP7LZOdTsHw@mail.gmail.com>
 <20150430033925.GA10288@cskk.homeip.net>
 <CANDiX9LCQpsJkfowQp-uovqH89aXnPaMjE14tCRrBPyV54B5SQ@mail.gmail.com>
Message-ID: <mhsp2k$dbt$1@ger.gmane.org>

On 30/04/15 05:28, boB Stepp wrote:

> That is what I have implemented as of today. I installed Git on my
> Windows PC where I have been doing my actual coding

This is off topic but due to your peculiar restrictions might
be useful so I thought I'd bring it up.

Do you have Cygwin installed on your PC?

Its a Unix-like user environment that runs on Windows including
Python and the other tools (including X windows). It makes
writing and testing code for a Unix box on a Windows box
very much easier.

If you haven't investigated it before I strongly recommend it.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Thu Apr 30 10:40:14 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 30 Apr 2015 09:40:14 +0100
Subject: [Tutor] Newbie problems
In-Reply-To: <465451395.1213571.1430366305635.JavaMail.yahoo@mail.yahoo.com>
References: <465451395.1213571.1430366305635.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <mhsppc$oak$1@ger.gmane.org>

On 30/04/15 04:58, Jag Sherrington wrote:
> Can anyone please tell me what I am doing wrong?As this code I have for the Roulette Wheel colours exercise, won't work. number = int(input('Enter a number between 0 and 36: '))green_number = (0) red_number = (1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36) black_number = (2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 34, 29, 31, 33, 35)
> if number == green_number:    print('Number is Green')    elif number == red_number:    print('Number is Red')    elif number == black_number:        print('Number is Black')
> Thank you for any help, Jag

The first problem is that you are posting in HTML which is losing
all the code formatting, making it hard to read.

Also you don't actually tell us what doesn't work. If you get an
error message post it. If you get different results to what you
expect tell us what you expect and what you got.

For now I'll take a guess below...

number = int(input('Enter a number between 0 and 36: '))
green_number = (0)
red_number = (1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 
34, 36)
black_number = (2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 34, 
29, 31, 33, 35)
if number == green_number:
     print('Number is Green')
elif number == red_number:
     print('Number is Red')
elif number == black_number:
         print('Number is Black')

Note that you are testing the number for equality, which means it
must be exactly the same value.

But your red_number and black_number are both tuples of several
numbers so a single number will never equal a sequence of numbers.
You should use the 'in' test instead of equals.

Like

if number in red_number:


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From alan.gauld at btinternet.com  Thu Apr 30 10:46:49 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 30 Apr 2015 09:46:49 +0100
Subject: [Tutor] if/then statement and sql count rows
In-Reply-To: <CAAAQYPcgjRW2o8BNU_7ewiS=i=_-Pdv3LOK5f1oAjFw=dPAY2g@mail.gmail.com>
References: <CAAAQYPcgjRW2o8BNU_7ewiS=i=_-Pdv3LOK5f1oAjFw=dPAY2g@mail.gmail.com>
Message-ID: <mhsq5m$v80$1@ger.gmane.org>

On 30/04/15 03:59, Spencer For Friends wrote:

>      class PriceCheck(object):
>          def __init__(self, db):
>              self.conn = sqlite3.connect(db)
>              self.c = self.conn.cursor()
>
>
>          def query(self, arg, cardname):
>              self.c.execute(arg, cardname)
>              return self.c

You are returning the cursor object here.
That's probably not what the user of your code wants,
it would be better to return the actual result.
You can get that using fetchone() or fetchall()
Since count() can only return one value fetchone()
would be best here.

return self.c.fetchone()

>          def __del__(self):
>              self.conn.close()
>
>      def display():
>      #Connect To DB and Get Price of Matched book.
>          getbookprice = PriceCheck("arbbase.sqlite")
>          for row in getbookprice.query(sql, ([book_name])):

Insert a debug statement here:

print type(row), ':', row

And see if what you get is what you expect.

>              if row == 0:
>                  print 'no row was found'
>              else:
>                 print 'Yep its there!'
>                  print row

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From robertvstepp at gmail.com  Thu Apr 30 16:34:44 2015
From: robertvstepp at gmail.com (boB Stepp)
Date: Thu, 30 Apr 2015 09:34:44 -0500
Subject: [Tutor] How to use Git from Windows PC for files on Solaris
 machine where Git cannot be installed?
In-Reply-To: <5541B1BD.6030600@davea.name>
References: <CANDiX9+=jFBm+jFD2PO8mdXY19fEbiJ893e=LuSvP7LZOdTsHw@mail.gmail.com>
 <20150430033925.GA10288@cskk.homeip.net>
 <CANDiX9LCQpsJkfowQp-uovqH89aXnPaMjE14tCRrBPyV54B5SQ@mail.gmail.com>
 <5541B1BD.6030600@davea.name>
Message-ID: <CANDiX9JcSc1-AbaUcyVOVDJH=UYhKNok1mZDMVevP=pehSPd-A@mail.gmail.com>

On Wed, Apr 29, 2015 at 11:38 PM, Dave Angel <davea at davea.name> wrote:
> On 04/30/2015 12:28 AM, boB Stepp wrote:
>>
>> The main danger as I see it is that if I am not careful, then the code
>> on the dev environment could diverge from the state of code on my
>> Windows PC, i.e., I forgot to do the scp part. But when I am actively
>> working on a section of code I always insert a few print statements
>> (Py 2.4!) to verify I am getting what I should when I test it
>> out--even if I don't have an actual problem yet. And so far this has
>> immediately revealed those few instances so far when I forgot to save
>> to the dev machine (Usually when someone has interrupted my workflow,
>> a near constant occurrence at work.).
>>
>>
>
> Add an automatic file copy to the save-key definition in your editor. Then
> whenever you save the file locally, you'll also be copying it to the master
> location.

Many, many thanks, Dave! This was easily done in and will match my
local and remote file saves exactly as they need to be. It did not
even occur to me that this feature existed. Heavy, sigh! I have so
many blind spots...


-- 
boB

From roel at roelschroeven.net  Thu Apr 30 21:22:58 2015
From: roel at roelschroeven.net (Roel Schroeven)
Date: Thu, 30 Apr 2015 21:22:58 +0200
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
In-Reply-To: <mhrn92$gc6$1@ger.gmane.org>
References: <55404A9D.5010103@gmail.com> <mhq3dh$lnt$1@ger.gmane.org>
 <554100DD.3080000@gmail.com> <mhr1n5$lj7$1@ger.gmane.org>
 <mhrhdi$ba2$1@ger.gmane.org> <mhrn92$gc6$1@ger.gmane.org>
Message-ID: <mhtvei$hlr$1@ger.gmane.org>

Alan Gauld schreef op 2015-04-30 00:51:

 > ...

> Trying to visually scan for _ or even __ is hard. Also different
> fonts make _ and __ hard to distinguish.

 > ...

> But they will be. Almost for certain. It's human nature and the nature 
> of code maintenance. If it's there somebody will find a use for it. The 
> fact that 5 or 10 years earlier the author didn't intend for it to be 
> used is immaterial.

Summarizing a bit, I think you make two main points (please correct me 
if I'm wrong):

[1] Visually scanning for _ or __ is hard, and _ are __ hard to 
distinguish from each other.

Personally, I find it easy to scan for them, but I think I can see whee 
you're coming from. Python tends to prefer words and tends to dislike 
symbols compared to e.g. C, C++, and certainly Perl. One could argue 
that using _ or __ goes against that, though to me it's not a problem. 
We're still very far from Perl's line noise.
It's true that _ and __ can be difficult to be distinguished from each 
other, but that's also not a problem to me, since I don't care about 
their values.


[2] Inevitably, sooner or later someone somewhere will start using _ or 
__ despite the fact that by convention they should not be used.

I have to admit that I have no experience programming in larger teams, 
and was blissfully unaware of the problems you describe. I think I can 
see how it might be better to avoid __ rather than try to enforce good 
coding discipline.


I still feel __ to be valuable, but I can see now where your dislike for 
it is coming from. Thank you for your insights!


Best regards,
Roel

-- 
The saddest aspect of life right now is that science gathers knowledge
faster than society gathers wisdom.
   -- Isaac Asimov

Roel Schroeven


From davea at davea.name  Thu Apr 30 21:33:49 2015
From: davea at davea.name (Dave Angel)
Date: Thu, 30 Apr 2015 15:33:49 -0400
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
In-Reply-To: <mhtvei$hlr$1@ger.gmane.org>
References: <55404A9D.5010103@gmail.com> <mhq3dh$lnt$1@ger.gmane.org>
 <554100DD.3080000@gmail.com> <mhr1n5$lj7$1@ger.gmane.org>
 <mhrhdi$ba2$1@ger.gmane.org> <mhrn92$gc6$1@ger.gmane.org>
 <mhtvei$hlr$1@ger.gmane.org>
Message-ID: <5542839D.10700@davea.name>

On 04/30/2015 03:22 PM, Roel Schroeven wrote:
> Alan Gauld schreef op 2015-04-30 00:51:
>
>  > ...
>
>> Trying to visually scan for _ or even __ is hard. Also different
>> fonts make _ and __ hard to distinguish.
>
>  > ...
>
>> But they will be. Almost for certain. It's human nature and the nature
>> of code maintenance. If it's there somebody will find a use for it.
>> The fact that 5 or 10 years earlier the author didn't intend for it to
>> be used is immaterial.
>
> Summarizing a bit, I think you make two main points (please correct me
> if I'm wrong):
>
> [1] Visually scanning for _ or __ is hard, and _ are __ hard to
> distinguish from each other.
>
> Personally, I find it easy to scan for them, but I think I can see whee
> you're coming from. Python tends to prefer words and tends to dislike
> symbols compared to e.g. C, C++, and certainly Perl. One could argue
> that using _ or __ goes against that, though to me it's not a problem.
> We're still very far from Perl's line noise.
> It's true that _ and __ can be difficult to be distinguished from each
> other, but that's also not a problem to me, since I don't care about
> their values.
>
>
> [2] Inevitably, sooner or later someone somewhere will start using _ or
> __ despite the fact that by convention they should not be used.
>
> I have to admit that I have no experience programming in larger teams,
> and was blissfully unaware of the problems you describe. I think I can
> see how it might be better to avoid __ rather than try to enforce good
> coding discipline.
>
>
> I still feel __ to be valuable, but I can see now where your dislike for
> it is coming from. Thank you for your insights!
>

Well, are you aware that _ has a meaning in the debugger?  It holds the 
last value of an expression that wasn't assigned to a variable.  or 
something like that.

So even if you don't have any coworkers, you might trip on someone 
else's assumptions.

To see what I'm talking about:

 >>> 3*4
12
 >>> print(_)
12



> Best regards,
> Roel
>


-- 
DaveA

From roel at roelschroeven.net  Thu Apr 30 21:52:59 2015
From: roel at roelschroeven.net (Roel Schroeven)
Date: Thu, 30 Apr 2015 21:52:59 +0200
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
In-Reply-To: <5542839D.10700@davea.name>
References: <55404A9D.5010103@gmail.com> <mhq3dh$lnt$1@ger.gmane.org>
 <554100DD.3080000@gmail.com> <mhr1n5$lj7$1@ger.gmane.org>
 <mhrhdi$ba2$1@ger.gmane.org> <mhrn92$gc6$1@ger.gmane.org>
 <mhtvei$hlr$1@ger.gmane.org> <5542839D.10700@davea.name>
Message-ID: <mhu16r$gf4$1@ger.gmane.org>

Dave Angel schreef op 2015-04-30 21:33:
> Well, are you aware that _ has a meaning in the debugger?  It holds the 
> last value of an expression that wasn't assigned to a variable.  or 
> something like that.

Yes, I know the meaning of _ in Python's interactive mode. It's 
something I sometimes use for convenience, but never really rely on. To 
me interactive mode is for trying out simple things, not for serious stuff.

Anyway, as explained in this style guide it's better to use __ anyway 
instead of _:

http://docs.python-guide.org/en/latest/writing/style/#create-an-ignored-variable


-- 
The saddest aspect of life right now is that science gathers knowledge
faster than society gathers wisdom.
   -- Isaac Asimov

Roel Schroeven


From alan.gauld at btinternet.com  Thu Apr 30 23:12:37 2015
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 30 Apr 2015 22:12:37 +0100
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
In-Reply-To: <mhtvei$hlr$1@ger.gmane.org>
References: <55404A9D.5010103@gmail.com> <mhq3dh$lnt$1@ger.gmane.org>
 <554100DD.3080000@gmail.com> <mhr1n5$lj7$1@ger.gmane.org>
 <mhrhdi$ba2$1@ger.gmane.org> <mhrn92$gc6$1@ger.gmane.org>
 <mhtvei$hlr$1@ger.gmane.org>
Message-ID: <mhu5s2$vb1$1@ger.gmane.org>

On 30/04/15 20:22, Roel Schroeven wrote:
> Alan Gauld schreef op 2015-04-30 00:51:

> Summarizing a bit, I think you make two main points (please correct me
> if I'm wrong):

Your quite correct.

I'm probably a bit paranoid but as I said I spent a
significant bit of my production-programming career
(about 40%) on maintenance projects and I've seen the
horrors that come from uninitialised variables, misused
names etc etc. And any kind of meaningless symbiol
(even if the meaning is not needed at the time).
And in a maintenance team where you are targetted
to fix, say, 4 bugs per day, a "horror" is anything
that adds more than say 15-20 minutes to the process!

> [1] Visually scanning for _ or __ is hard, and _ are __ hard to
> distinguish from each other.
>
> Personally, I find it easy to scan for them, but I think I can see whee
> you're coming from. Python tends to prefer words and tends to dislike
> symbols

Yes but worse in this cae is tat Python uses __ for special
purposes so if there is a __ near to a variable name the reader
is likely to assume its just a pre-pended dunder marker rather
than a separate name. It also makes searching for dunders harder
since there are likely to be quite a few in the code already.
(yes you can create a regex search but making it reliable
is quite tricky.)

> [2] Inevitably, sooner or later someone somewhere will start using _ or
> __ despite the fact that by convention they should not be used.
>
> I have to admit that I have no experience programming in larger teams,
> and was blissfully unaware of the problems you describe.

Again my experience is not typical of the tutor forum, but
some tutor readers may go on to bigger things and bad habits
once learned become permanent...

My smallest project team was 7  programmers producing 80,000
lines of code. Next smallest 18, producing 250,000.
Most of my projects have had over 100 programmers and several
million LOC (usually C++ or COBOL)

One project had over 1000 programmers and produced 60 million
LOC using 7(?) different programming languages. (I ran one of
the maintenance teams of ~10 coders all fresh from  uni')

Like I say I get paranoid about some things :-)


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From lac at openend.se  Thu Apr 30 23:59:09 2015
From: lac at openend.se (Laura Creighton)
Date: Thu, 30 Apr 2015 23:59:09 +0200
Subject: [Tutor] Good Taste Question: Using SQLite3 in Python
In-Reply-To: Message from Roel Schroeven <roel@roelschroeven.net>
 of "Thu, 30 Apr 2015 21:22:58 +0200." <mhtvei$hlr$1@ger.gmane.org>
References: <55404A9D.5010103@gmail.com> <mhq3dh$lnt$1@ger.gmane.org>
 <554100DD.3080000@gmail.com> <mhr1n5$lj7$1@ger.gmane.org>
 <mhrhdi$ba2$1@ger.gmane.org>
 <mhrn92$gc6$1@ger.gmane.org><mhtvei$hlr$1@ger.gmane.org>
Message-ID: <201504302159.t3ULxAiw010580@fido.openend.se>

The fact that _ and __ are intended as throw away values is only clear
to people who have read a particular doc about coding styles.  If you
haven't read the doc, you don't know what is going on.  I name my
throw away variables junk, and if there are lots of them, for instance
when I am reading from a list of tuples, but only care about the fourth
item in each tuple, its 'junk1, junk2, junk3 ...'

So far I have yet to meet somebody who wasn't immediately aware that
I did not care about those values.

Laura