From denis.spir at gmail.com  Wed Jan  1 00:28:00 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 01 Jan 2014 00:28:00 +0100
Subject: [Tutor] lists of lists: more Chutes & Ladders!
In-Reply-To: <CAO5ffbZtg53iBQ7poPq7yFr6-xezVdkMZuC45pO0Vm5PXoFJLw@mail.gmail.com>
References: <CAO5ffbbsbFTWJD4G=78uxmtD_H_HsB1atmOY3Ty2emhPGqZ9cQ@mail.gmail.com>
 <52C28DF8.7010506@gmail.com>
 <CAO5ffbZtg53iBQ7poPq7yFr6-xezVdkMZuC45pO0Vm5PXoFJLw@mail.gmail.com>
Message-ID: <52C35300.40100@gmail.com>

On 12/31/2013 09:46 PM, Keith Winston wrote:
> Thanks Denis, I found out about the iter builtin last night, a few hours
> after I'd coded/posted that. Oops. Thanks for your other comments, I am
> clearer now about the distinction of creating a new, empty list vs.
> clearing the same list out, and the subsequent implications on other
> symbols bound to the same list (is that the right language?).

Thanks, thus I did not spoil my time ;-)

> Not to beat a dead horse: you mention the name of the "game" method: in my
> code, "game" plays a game of Chutes & Ladders (does a series of moves until
> the game is over), compiles the statistics from said game, and passes
> those, as a list of ints & lists, to be gathered into a list of lists at
> the next level ("games" is the list of lists, composed of many "game"
> lists). I should absolutely document it better, but does that still not
> seem like a good name to you? Thanks for your feedback.

In the part you showed us, unless my memory trumps myself, the method barely 
collected stat data _about_ the game. I did not look like representing the 
game's *playing* globally. But indeed, it was probably only a snippet.

Well, actually the case looks ambiguous. If at all possible, i would separate in 
a sub-method the piece of code that compiles statistic data. Call it stats or 
game_stats or whatever looks clear and correct. The super-method that plays the 
game and, as an after-thought (even if it's not the case for you) calls this 
sub-method that collects data _about_ the game, may be called 'play'. This, 
because the whole of the app is, conceptually, the 'game', isn't it? or am I 
wrong on this point?

Also, again conceptually, this method is an action (playing the game), thus a 
verb fits well as a name for it. A function that only computes new data (which 
is the case for stats) would requires a noun as name, the name of what it 
computes. But this is all rather personal and you may have a different 
perspective on all this. (However, this scheme of verbs for actions and nouns 
for functions works fine, I'm not inventing it; for this reason, I do recommend 
it as a consistent starting point; then you may later forge your own standard & 
shortcuts, or adopt the ones of your preferred programming community).

Denis

From steve at pearwood.info  Wed Jan  1 01:26:20 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 1 Jan 2014 11:26:20 +1100
Subject: [Tutor] subtyping builtin type
In-Reply-To: <52C2D64B.4060400@gmail.com>
References: <52C2D64B.4060400@gmail.com>
Message-ID: <20140101002620.GJ29356@ando>

On Tue, Dec 31, 2013 at 03:35:55PM +0100, spir wrote:
> Hello,
> 
> I don't remember exactly how to do that. As an example:
> 
> class Source (str):
>     __slots__ = ['i', 'n']
>     def __init__ (self, string):
>         self.i = 0                  # current matching index in source
>         self.n = len(string)        # number of ucodes (Unicode code points)
>         #~ str.__init__(self, string)

The easiest way to do that is:

class Source(str):
    def __init__(self, *args, **kwargs):
        self.i = 0
        self.n = len(self)


As a (premature) memory optimization, you can use __slots__ to reduce 
the amount of memory per instance. But this (probably) is the wrong way 
to solve this problem. Your design makes Source a kind of string:

issubclass(Source, str) 
=> True

I expect that it should not be. (Obviously I'm making some assumptions 
about the design here.) To decide whether you should use subclassing 
here, ask yourself a few questions:

* Does it make sense to call string methods on Source objects? In 
  Python 3.3, there are over 40 public string methods. If *just one* 
  of them makes no sense for a Source object, then Source should not
  be a subclass of str.

  e.g. source.isnumeric(), source.isidentifier()

* Do you expect to pass Source objects to arbitrary functions which
  expect strings, and have the result be meaningful?

* Does it make sense for Source methods to return plain strings?
  source.upper() returns a str, not a Source object.

* Is a Source thing a kind of string? If so, what's the difference
  between a Source and a str? Why not just use a str?

  If all you want is to decorate a string with a couple of extra
  pieces of information, then a limitation of Python is that you 
  can only do so by subclassing.

* Or does a Source thing *include* a string as a component part of
  it? If that is the case -- and I think it is -- then composition
  is the right approach.


The difference between has-a and is-a relationships are critical. I 
expect that the right relationship should be:

    a Source object has a string

rather than "is a string". That makes composition a better design than 
inheritance. Here's a lightweight mutable solution, where all three 
attributes are public and free to be varied after initialisation:

class Source:
    def __init__(self, string, i=0, n=None):
        if n is None:
            n = len(string)
        self.i = i
        self.n = n
        self.string = string


An immutable solution is nearly as easy:

from collections import namedtuple

class Source(namedtuple("Source", "string i n")):
    def __new__(cls, string, i=0, n=None):
        if n is None: 
            n = len(string)
        return super(Source, cls).__new__(cls, string, i, n)


Here's a version which makes the string attribute immutable, and the i 
and n attributes mutable:

class Source:
    def __init__(self, string, i=0, n=None):
        if n is None:
            n = len(string)
        self.i = i
        self.n = n
        self._string = string
    @property
    def string(self):
        return self._string



-- 
Steven

From eryksun at gmail.com  Wed Jan  1 03:28:03 2014
From: eryksun at gmail.com (eryksun)
Date: Tue, 31 Dec 2013 21:28:03 -0500
Subject: [Tutor] subtyping builtin type
In-Reply-To: <20140101002620.GJ29356@ando>
References: <52C2D64B.4060400@gmail.com> <20140101002620.GJ29356@ando>
Message-ID: <CACL+1ashPtWX9bN=LZmXJBxnrDO-BcaLNp-k79goShZjcY14JQ@mail.gmail.com>

On Tue, Dec 31, 2013 at 7:26 PM, Steven D'Aprano <steve at pearwood.info> wrote:
>
> from collections import namedtuple
>
> class Source(namedtuple("Source", "string i n")):
>     def __new__(cls, string, i=0, n=None):
>         if n is None:
>             n = len(string)
>         return super(Source, cls).__new__(cls, string, i, n)

namedtuple is a factory to create a tuple subclass that has properties
that use operator.itemgetter, a __dict__ property that returns a
collections.OrderedDict, plus the convenience functions _make and
_replace.

It also sets __slots__ = () to prevent instances from getting a dict.
If you subclass a 2nd time, remember to also set __slots__ = (). But
this only matters if you need better performance and smaller memory
footprint when creating thousands of instances.

From eryksun at gmail.com  Wed Jan  1 04:00:32 2014
From: eryksun at gmail.com (eryksun)
Date: Tue, 31 Dec 2013 22:00:32 -0500
Subject: [Tutor] lists of lists: more Chutes & Ladders!
In-Reply-To: <52C28DF8.7010506@gmail.com>
References: <CAO5ffbbsbFTWJD4G=78uxmtD_H_HsB1atmOY3Ty2emhPGqZ9cQ@mail.gmail.com>
 <52C28DF8.7010506@gmail.com>
Message-ID: <CACL+1auhtpmDRauqNva5vrGeLCS2n34Oj47iWhyeLsW0ZVBopA@mail.gmail.com>

On Tue, Dec 31, 2013 at 4:27 AM, spir <denis.spir at gmail.com> wrote:
> In addition, "iter" is also the name of a builtin function, like "print".

While iter is a built-in function, it would be clearer if you
referenced the __builtins__ namespace. Built-in objects are linked
into the interpreter, either statically or from a shared library (.so,
.pyd). But the __builtins__ namespace can and does include names for
non-built-in objects (e.g. help and exit). The important point in this
context is that iter is in the builtins module, not that it's a
built-in function. There are lots of built-in objects that aren't in
builtins.

From steve at pearwood.info  Wed Jan  1 04:53:06 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 1 Jan 2014 14:53:06 +1100
Subject: [Tutor] lists of lists: more Chutes & Ladders!
In-Reply-To: <CACL+1auhtpmDRauqNva5vrGeLCS2n34Oj47iWhyeLsW0ZVBopA@mail.gmail.com>
References: <CAO5ffbbsbFTWJD4G=78uxmtD_H_HsB1atmOY3Ty2emhPGqZ9cQ@mail.gmail.com>
 <52C28DF8.7010506@gmail.com>
 <CACL+1auhtpmDRauqNva5vrGeLCS2n34Oj47iWhyeLsW0ZVBopA@mail.gmail.com>
Message-ID: <20140101035305.GK29356@ando>

On Tue, Dec 31, 2013 at 10:00:32PM -0500, eryksun wrote:
> On Tue, Dec 31, 2013 at 4:27 AM, spir <denis.spir at gmail.com> wrote:
> > In addition, "iter" is also the name of a builtin function, like "print".
> 
> While iter is a built-in function, it would be clearer if you
> referenced the __builtins__ namespace. 

Don't use __builtins__!

Firstly, it's an implementation detail only in CPython, not part of the 
language. So it doesn't exist in Jython or IronPython:

Jython 2.5.1+ (Release_2_5_1, Aug 4 2010, 07:18:19)
[OpenJDK Server VM (Sun Microsystems Inc.)] on java1.6.0_27
Type "help", "copyright", "credits" or "license" for more information.
>>> import __builtins__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named __builtins__

__builtins__ with-an-s is a crappy hack that has never worked correctly 
and has caused more confusion than help:

https://mail.python.org/pipermail/python-3000/2007-March/006170.html

"Restricted mode" in CPython has never worked correctly, __builtins__ 
has always been an implementation-specific detail, and you should never 
use it. The one you actually want is "__builtin__" (no "s") in Python 2, 
or "builtins" (no underscores) in Python 3.


> Built-in objects are linked
> into the interpreter, either statically or from a shared library (.so,
> .pyd). But the __builtins__ namespace can and does include names for
> non-built-in objects (e.g. help and exit).

Only when running interactively, and only when site.py runs. If you 
remove or disable site.py, the help and exit functions don't get added.

Actually, there's nothing special about site.py, anyone or anything 
could monkey-patch builtins. Don't do this:

py> spam  # Does spam variable exist?
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
py> import builtins
py> builtins.spam = "spam spam spam"
py> del builtins
py> spam
'spam spam spam'



> The important point in this
> context is that iter is in the builtins module, not that it's a
> built-in function. There are lots of built-in objects that aren't in
> builtins.


I'm afraid I've lost the context, and don't understand why this is 
important. It's true that not all built-in objects are in builtins, and 
not all objects in builtins are built-in, but other than for pedantic 
correctness, why does this matter?


-- 
Steven

From eryksun at gmail.com  Wed Jan  1 07:13:35 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 1 Jan 2014 01:13:35 -0500
Subject: [Tutor] lists of lists: more Chutes & Ladders!
In-Reply-To: <20140101035305.GK29356@ando>
References: <CAO5ffbbsbFTWJD4G=78uxmtD_H_HsB1atmOY3Ty2emhPGqZ9cQ@mail.gmail.com>
 <52C28DF8.7010506@gmail.com>
 <CACL+1auhtpmDRauqNva5vrGeLCS2n34Oj47iWhyeLsW0ZVBopA@mail.gmail.com>
 <20140101035305.GK29356@ando>
Message-ID: <CACL+1avVwUxZVCJLT3MYJa88Ux08QXTKOnPVvrALz0j6uGbNdg@mail.gmail.com>

On Tue, Dec 31, 2013 at 10:53 PM, Steven D'Aprano <steve at pearwood.info> wrote:
>
> __builtins__ with-an-s is a crappy hack that has never worked correctly
> and has caused more confusion than help:
>
> https://mail.python.org/pipermail/python-3000/2007-March/006170.html
>
> "Restricted mode" in CPython has never worked correctly, __builtins__
> has always been an implementation-specific detail, and you should never
> use it. The one you actually want is "__builtin__" (no "s") in Python 2,
> or "builtins" (no underscores) in Python 3.

But I didn't say to use the "__builtins__" module.  __builtin__ works
in Jython, but the module I referenced was "builtins", per the 3.x
example given by Denis.

I'm definitely not talking about the weird hack that __builtins__ is a
module in __main__ in CPython. I've never understood the reason for
that, and I loathe it. In every other module it's a dict:

    >>> d = {}
    >>> exec("x = 1", d)
    >>> type(d['__builtins__'])
    <class 'dict'>

I'm not familiar with the implementation of Jython's builtins
namespace. Using the name __builtins__ was based on CPython. Just to
be clear, I'm talking about the builtins namespace and scope --
however it's implemented in Jython or IronPython. I don't use them and
never plan to, so I'm grateful for the correction, Steven.

>> But the __builtins__ namespace can and does include names for
>> non-built-in objects (e.g. help and exit).
>
> Only when running interactively, and only when site.py runs. If you
> remove or disable site.py, the help and exit functions don't get added.

I'm aware of that, and have even mentioned it at least twice in the past.

>> The important point in this
>> context is that iter is in the builtins module, not that it's a
>> built-in function. There are lots of built-in objects that aren't in
>> builtins.
>
>
> I'm afraid I've lost the context, and don't understand why this is
> important. It's true that not all built-in objects are in builtins, and
> not all objects in builtins are built-in, but other than for pedantic
> correctness, why does this matter?

Denis said:

> "iter" is also the name of a builtin function, like "print"

My point was that the issue with iter is a namespace issue. It doesn't
matter that it's a built-in function like "print". Denis could have
meant that either way, so I thought it important to clarify. Why? A
while back there was a thread on the list confusing "built-in"
functions/methods in the io module and the builtins namespace, and
there was even an erroneous bug report filed on a doc string.

https://mail.python.org/pipermail/tutor/2013-June/096218.html
http://bugs.python.org/issue18249

From keithwins at gmail.com  Wed Jan  1 08:01:50 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 1 Jan 2014 02:01:50 -0500
Subject: [Tutor] Shelve & immutable objects
Message-ID: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>

I'm working my way slowly through Programming Python by Mark Lutz, and as
an example of data persistence, he uses this example:


-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140101/2c51cb5a/attachment.html>

From keithwins at gmail.com  Wed Jan  1 08:06:42 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 1 Jan 2014 02:06:42 -0500
Subject: [Tutor] Shelve & immutable objects
In-Reply-To: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
References: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
Message-ID: <CAO5ffbYDVEBpq=4twoENLdymCRMuaYxZbotK546a9s4NazzUNw@mail.gmail.com>

So sorry, I hit return: here's the example:

import shelve
db = shelve.open('class-shelve')

sue = db['sue']
sue.giveRaise(.25)
db['sue'] = sue

tom = db['tom']
tom.giveRaise(.20)
db['tom'] = tom
db.close()

Is it possible to dispense with the assignment/reassignment and just use

(open shelve)
db['sue'].giveRaise(.25)
db['sue'].giveRaise(.25)
(close shelve)

or is the assignment (or bounding?) necessary to unshelve/reshelve the
items...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140101/7840b2dd/attachment.html>

From dyoo at hashcollision.org  Wed Jan  1 08:22:50 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 31 Dec 2013 23:22:50 -0800
Subject: [Tutor] Shelve & immutable objects
In-Reply-To: <CAO5ffbYDVEBpq=4twoENLdymCRMuaYxZbotK546a9s4NazzUNw@mail.gmail.com>
References: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
 <CAO5ffbYDVEBpq=4twoENLdymCRMuaYxZbotK546a9s4NazzUNw@mail.gmail.com>
Message-ID: <CAGZAPF4nC+CZtRr=h_TkS_Y=OaXhKOnnBwJ4F-k4yzMfVJzHNg@mail.gmail.com>

According to:

   http://docs.python.org/2/library/shelve.html

The shelve can be opened in 'writeback' mode, which I think might be
relevant to your question.

"By default modified objects are written only when assigned to the
shelf (see Example). If the optional writebackparameter is set to
True, all entries accessed are also cached in memory, and written back
on sync() and close(); this can make it handier to mutate mutable
entries in the persistent dictionary, but, if many entries are
accessed, it can consume vast amounts of memory for the cache, and it
can make the close operation very slow since all accessed entries are
written back (there is no way to determine which accessed entries are
mutable, nor which ones were actually mutated)."

Let's try it:

##################################################
>>> import shelve
>>> db = shelve.open('class-shelve')
>>> db['a-list'] = [1, 2, 3]
>>> db.close()
>>> db = shelve.open('class-shelve', writeback=True)
>>> db['a-list'].append("four")
>>> db.close()
>>> db = shelve.open('class-shelve')
>>> db['a-list']
[1, 2, 3, 'four']
##################################################


So yes, you should be able to use a shelve in writeback mode to
automatically persist the mutable structures.  That being said, the
docs do say to be aware of the implications: it means every accessed
entry's going to be re-persisted because the shelve does not really
watch for mutations: it just checks for access.

Happy New Year!

From dyoo at hashcollision.org  Wed Jan  1 08:07:15 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 31 Dec 2013 23:07:15 -0800
Subject: [Tutor] Shelve & immutable objects
In-Reply-To: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
References: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
Message-ID: <CAGZAPF5u=3p6CNoHrfjpw42gHDu0z=vwfs8okFdVBeZPaDtnNA@mail.gmail.com>

On Tue, Dec 31, 2013 at 11:01 PM, Keith Winston <keithwins at gmail.com> wrote:
> I'm working my way slowly through Programming Python by Mark Lutz, and as an
> example of data persistence, he uses this example:


Ooops; the email got cut off a bit early.  Can you try again?

From denis.spir at gmail.com  Wed Jan  1 08:55:24 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 01 Jan 2014 08:55:24 +0100
Subject: [Tutor] lists of lists: more Chutes & Ladders!
In-Reply-To: <CACL+1avVwUxZVCJLT3MYJa88Ux08QXTKOnPVvrALz0j6uGbNdg@mail.gmail.com>
References: <CAO5ffbbsbFTWJD4G=78uxmtD_H_HsB1atmOY3Ty2emhPGqZ9cQ@mail.gmail.com>
 <52C28DF8.7010506@gmail.com>
 <CACL+1auhtpmDRauqNva5vrGeLCS2n34Oj47iWhyeLsW0ZVBopA@mail.gmail.com>
 <20140101035305.GK29356@ando>
 <CACL+1avVwUxZVCJLT3MYJa88Ux08QXTKOnPVvrALz0j6uGbNdg@mail.gmail.com>
Message-ID: <52C3C9EC.5080203@gmail.com>

On 01/01/2014 07:13 AM, eryksun wrote:
>> >I'm afraid I've lost the context, and don't understand why this is
>> >important. It's true that not all built-in objects are in builtins, and
>> >not all objects in builtins are built-in, but other than for pedantic
>> >correctness, why does this matter?
> Denis said:
>
>> >"iter" is also the name of a builtin function, like "print"
> My point was that the issue with iter is a namespace issue. It doesn't
> matter that it's a built-in function like "print". Denis could have
> meant that either way, so I thought it important to clarify. Why? A
> while back there was a thread on the list confusing "built-in"
> functions/methods in the io module and the builtins namespace, and
> there was even an erroneous bug report filed on a doc string.
>
> https://mail.python.org/pipermail/tutor/2013-June/096218.html
> http://bugs.python.org/issue18249

You are very right, eryksyn, I was not clear at all, in fact it was not clear in 
my knowledge.

My point was: `iter` the func exists in python (built-in with '-'), one may use 
it at times. Giving an application var this name hides, which accosionnally 
leads to bugs. I have been bitten by such a bug more than once in the past, and 
once hard to find, asp. with the built-in func `range` (a very tempting var 
name, isn't it?).

Denis



From dyoo at hashcollision.org  Wed Jan  1 09:04:38 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Wed, 1 Jan 2014 00:04:38 -0800
Subject: [Tutor] lists of lists: more Chutes & Ladders!
In-Reply-To: <52C3C9EC.5080203@gmail.com>
References: <CAO5ffbbsbFTWJD4G=78uxmtD_H_HsB1atmOY3Ty2emhPGqZ9cQ@mail.gmail.com>
 <52C28DF8.7010506@gmail.com>
 <CACL+1auhtpmDRauqNva5vrGeLCS2n34Oj47iWhyeLsW0ZVBopA@mail.gmail.com>
 <20140101035305.GK29356@ando>
 <CACL+1avVwUxZVCJLT3MYJa88Ux08QXTKOnPVvrALz0j6uGbNdg@mail.gmail.com>
 <52C3C9EC.5080203@gmail.com>
Message-ID: <CAGZAPF4MtSp1ukv4CxP5JPh+ZbzdTTy0K0MJVYZRvO=wqDWvdQ@mail.gmail.com>

> My point was: `iter` the func exists in python (built-in with '-'), one may
> use it at times. Giving an application var this name hides, which
> accosionnally leads to bugs. I have been bitten by such a bug more than once
> in the past, and once hard to find, asp. with the built-in func `range` (a
> very tempting var name, isn't it?).

Just as a small side note: there are linters for Python that will warn
if we are trying to redefine a built-in.  Pylint, for example, has
warning W0622 "Redefining built-in" to catch this class of gotchas.

    http://www.pylint.org/

From breamoreboy at yahoo.co.uk  Wed Jan  1 10:04:27 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 01 Jan 2014 09:04:27 +0000
Subject: [Tutor] lists of lists: more Chutes & Ladders!
In-Reply-To: <CAGZAPF4MtSp1ukv4CxP5JPh+ZbzdTTy0K0MJVYZRvO=wqDWvdQ@mail.gmail.com>
References: <CAO5ffbbsbFTWJD4G=78uxmtD_H_HsB1atmOY3Ty2emhPGqZ9cQ@mail.gmail.com>
 <52C28DF8.7010506@gmail.com>
 <CACL+1auhtpmDRauqNva5vrGeLCS2n34Oj47iWhyeLsW0ZVBopA@mail.gmail.com>
 <20140101035305.GK29356@ando>
 <CACL+1avVwUxZVCJLT3MYJa88Ux08QXTKOnPVvrALz0j6uGbNdg@mail.gmail.com>
 <52C3C9EC.5080203@gmail.com>
 <CAGZAPF4MtSp1ukv4CxP5JPh+ZbzdTTy0K0MJVYZRvO=wqDWvdQ@mail.gmail.com>
Message-ID: <la0lme$6p5$1@ger.gmane.org>

On 01/01/2014 08:04, Danny Yoo wrote:
>> My point was: `iter` the func exists in python (built-in with '-'), one may
>> use it at times. Giving an application var this name hides, which
>> accosionnally leads to bugs. I have been bitten by such a bug more than once
>> in the past, and once hard to find, asp. with the built-in func `range` (a
>> very tempting var name, isn't it?).
>
> Just as a small side note: there are linters for Python that will warn
> if we are trying to redefine a built-in.  Pylint, for example, has
> warning W0622 "Redefining built-in" to catch this class of gotchas.
>
>      http://www.pylint.org/

As I pointed out on 18/12/2013 and Walter Prins followed up on, you can 
use pylint in Eclipse/Pydev as you type, must have saved me eons.  I'd 
assume other IDEs have similar mechanisms.

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

Mark Lawrence


From denis.spir at gmail.com  Wed Jan  1 14:49:17 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 01 Jan 2014 14:49:17 +0100
Subject: [Tutor] subtyping builtin type
In-Reply-To: <20140101002620.GJ29356@ando>
References: <52C2D64B.4060400@gmail.com> <20140101002620.GJ29356@ando>
Message-ID: <52C41CDD.3000402@gmail.com>

On 01/01/2014 01:26 AM, Steven D'Aprano wrote:
> On Tue, Dec 31, 2013 at 03:35:55PM +0100, spir wrote:
>> Hello,
>>
>> I don't remember exactly how to do that. As an example:
>>
>> class Source (str):
>>      __slots__ = ['i', 'n']
>>      def __init__ (self, string):
>>          self.i = 0                  # current matching index in source
>>          self.n = len(string)        # number of ucodes (Unicode code points)
>>          #~ str.__init__(self, string)
>
> The easiest way to do that is:
>
> class Source(str):
>      def __init__(self, *args, **kwargs):
>          self.i = 0
>          self.n = len(self)

Thank you Steven for your help.

Well, I don't really get everything you say below, about possible alternatives, 
so I'll give a bit more details. The only point of Source is to have a string 
storing current index, somewhat like file (being read) on the filesystem. I take 
the opportunity to add a few features, but would do without Source altogether if 
it were not for 'i'.
The reason is: it is for parsing library, or hand-made parsers. Every matching 
func, representing a pattern (or "rule"), advances in source whenever mathc is 
ok, right? Thus in addition to return the form (of what was matched), they must 
return the new match index:
	return (form, i)
Symmetrically, every match func using another (meaning nearly all) receive this 
pair. (Less annoyingly, every math func also takes i as input, in addition to 
the src str.) (There are also a handful of other annoying points, consequences 
of those ones.)

If I have a string that stores its index, all of this mess is gone. It makes for 
clean and simple interfaces everywhere. Also (one of the consequences) I can 
directly provide match funcs to the user, instead of having to wrap them inside 
a func which only utility is to hide the additional index (in both input & output).

> As a (premature) memory optimization, you can use __slots__ to reduce
> the amount of memory per instance.

You're right! (I did it in fact for 'Form' subtypes, representing match results 
which are constantly instanciated, possibly millions of times in a single parse; 
but on the way i did it to Source as well, which is stupid ;-)

>But this (probably) is the wrong way
> to solve this problem. Your design makes Source a kind of string:
>
> issubclass(Source, str)
> => True
>
> I expect that it should not be. (Obviously I'm making some assumptions
> about the design here.)

Actually, doesn't matter whether issubclass or isinstance are true. But it must 
be a subtype to use string methods (including magic ones like slicing), as you 
say below.

>  To decide whether you should use subclassing
> here, ask yourself a few questions:
>
> * Does it make sense to call string methods on Source objects? In
>    Python 3.3, there are over 40 public string methods. If *just one*
>    of them makes no sense for a Source object, then Source should not
>    be a subclass of str.
>    e.g. source.isnumeric(), source.isidentifier()

Do you really mean "If *just one* of them makes no sense for a Source object, 
then Source should not be a subclass of str." ? Or should I understand "If *only 
one* of them does make sense for a Source object, then Source should not be a 
subclass of str." ?
Also, why? or rather why not make it a subtyp if I only use one method?

Actually, a handful of them are intensely used (indexing, slicing, the series of 
is* [eg isalnum], a few more as the prject moves on). This is far enough for me 
to make it a subtype.
Also, it fits semantically (conceptualy): a src is a str, that just happens to 
store a current index.

> * Do you expect to pass Source objects to arbitrary functions which
>    expect strings, and have the result be meaningful?

No, apart from string methods themselves. It's all internal to the lib.

> * Does it make sense for Source methods to return plain strings?
>    source.upper() returns a str, not a Source object.

Doesn't matter (it's parsing). The result Forms, when they hold snippets, hold 
plain strings, not Source's, thus all is fine.

> * Is a Source thing a kind of string? If so, what's the difference
>    between a Source and a str? Why not just use a str?

see above

>    If all you want is to decorate a string with a couple of extra
>    pieces of information, then a limitation of Python is that you
>    can only do so by subclassing.

That's it. But I don't know of any other solution in other langs, apart from 
composition, which in my view is clearly inferior:
* it does not fit semantics (conception)
* it's annoying syntactically (constant attribute access)

> * Or does a Source thing *include* a string as a component part of
>    it? If that is the case -- and I think it is -- then composition
>    is the right approach.

No, a source is conceptually like a string, not a kind of composite object with 
a string among other fields. (Again, think at a file.)

> The difference between has-a and is-a relationships are critical. I
> expect that the right relationship should be:
>
>      a Source object has a string
>
> rather than "is a string". That makes composition a better design than
> inheritance. Here's a lightweight mutable solution, where all three
> attributes are public and free to be varied after initialisation:

No, see above.

> class Source:
>      def __init__(self, string, i=0, n=None):
>          if n is None:
>              n = len(string)
>          self.i = i
>          self.n = n
>          self.string = string

Wrong solution for my case.

> An immutable solution is nearly as easy:
>
> from collections import namedtuple
>
> class Source(namedtuple("Source", "string i n")):
>      def __new__(cls, string, i=0, n=None):
>          if n is None:
>              n = len(string)
>          return super(Source, cls).__new__(cls, string, i, n)

An immutable version is fine. But what does this version bring me? a Source's 
code-string is immutable already. 'i' does change.

> Here's a version which makes the string attribute immutable, and the i
> and n attributes mutable:
>
> class Source:
>      def __init__(self, string, i=0, n=None):
>          if n is None:
>              n = len(string)
>          self.i = i
>          self.n = n
>          self._string = string
>      @property
>      def string(self):
>          return self._string

Again, what is here better than a plain subtyping of type 'str'? (And I dislike 
the principle of properties; i want to know whether it's a func call or plain 
attr access, on the user side. Bertrand Meyer's "uniform access principle" for 
Eiffel is what I dislike most in this lang ;-) [which has otherwise much to offer].)

Seems I have more to learn ;-) great!

Side-note: after reflexion, I guess I'll get rid of 'n'. 'n' is used each time I 
need in match funcs to check for end-of-source (meaning, in every low-level, 
lexical pattern, the ones that actually "eat" portions of source). I defined 'n' 
to have it at hand, but now I wonder whether it's not in fact less efficient 
than just writing len(src) instead of src.n, everywhere. (Since indeed python 
strings hold their length: it's certainly not an actual func call! Python lies ;-)

Denis

From keithwins at gmail.com  Wed Jan  1 17:43:42 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 1 Jan 2014 11:43:42 -0500
Subject: [Tutor] Shelve & immutable objects
In-Reply-To: <CAGZAPF4nC+CZtRr=h_TkS_Y=OaXhKOnnBwJ4F-k4yzMfVJzHNg@mail.gmail.com>
References: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
 <CAO5ffbYDVEBpq=4twoENLdymCRMuaYxZbotK546a9s4NazzUNw@mail.gmail.com>
 <CAGZAPF4nC+CZtRr=h_TkS_Y=OaXhKOnnBwJ4F-k4yzMfVJzHNg@mail.gmail.com>
Message-ID: <CAO5ffbbzxdAqqf8dqNiPLq=Tj4c=SZ3Aq3V-oB4WWvsk9ACTGQ@mail.gmail.com>

Thanks Danny, I don't understand the re-persisted part, but I'll look into
it. I realized I hadn't done enough homework to justify a question right
after I sent the first half of that one! Happy New Year!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140101/4e3b9bd7/attachment.html>

From breamoreboy at yahoo.co.uk  Wed Jan  1 22:55:41 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 01 Jan 2014 21:55:41 +0000
Subject: [Tutor] Shelve & immutable objects
In-Reply-To: <CAO5ffbbzxdAqqf8dqNiPLq=Tj4c=SZ3Aq3V-oB4WWvsk9ACTGQ@mail.gmail.com>
References: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
 <CAO5ffbYDVEBpq=4twoENLdymCRMuaYxZbotK546a9s4NazzUNw@mail.gmail.com>
 <CAGZAPF4nC+CZtRr=h_TkS_Y=OaXhKOnnBwJ4F-k4yzMfVJzHNg@mail.gmail.com>
 <CAO5ffbbzxdAqqf8dqNiPLq=Tj4c=SZ3Aq3V-oB4WWvsk9ACTGQ@mail.gmail.com>
Message-ID: <la22sj$fr7$1@ger.gmane.org>

On 01/01/2014 16:43, Keith Winston wrote:
> Thanks Danny, I don't understand the re-persisted part, but I'll look
> into it. I realized I hadn't done enough homework to justify a question
> right after I sent the first half of that one! Happy New Year!
>

You do infinitely more work than some who pose questions here!!!  Happy 
New Year to everybody.  And as I've already said elsewhere, let's hope 
2014 is more code, less bugs :)

-- 
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 Jan  2 03:21:25 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 2 Jan 2014 13:21:25 +1100
Subject: [Tutor] subtyping builtin type
In-Reply-To: <52C41CDD.3000402@gmail.com>
References: <52C2D64B.4060400@gmail.com> <20140101002620.GJ29356@ando>
 <52C41CDD.3000402@gmail.com>
Message-ID: <20140102022125.GL29356@ando>

On Wed, Jan 01, 2014 at 02:49:17PM +0100, spir wrote:
> On 01/01/2014 01:26 AM, Steven D'Aprano wrote:
> >On Tue, Dec 31, 2013 at 03:35:55PM +0100, spir wrote:
[...]
> I take the opportunity to add a few features, but would do 
> without Source altogether if it were not for 'i'.
> The reason is: it is for parsing library, or hand-made parsers. Every 
> matching func, representing a pattern (or "rule"), advances in source 
> whenever mathc is ok, right? Thus in addition to return the form (of what 
> was matched), they must return the new match index:
> 	return (form, i)

The usual way to do this is to make the matching index an attribute of 
the parser, not the text being parsed. In OOP code, you make the parser 
an object:

class Parser:
    def __init__(self, source):
        self.current_position = 0  # Always start at the beginning
        self.source = source
    def parse(self):
        ...

parser = Parser("some text to be parsed")
for token in parser.parse():
    handle(token)

The index is not an attribute of the source text, because the source 
text doesn't care about the index. Only the parser cares about the 
index, so it should be the responsibility of the parser to manage.


> Symmetrically, every match func using another (meaning nearly all) receive 
> this pair. (Less annoyingly, every math func also takes i as input, in 
> addition to the src str.) (There are also a handful of other annoying 
> points, consequences of those ones.)

The match functions are a property of the parser, not the source text. 
So they should be methods on a Parser object. Since they need to track 
the index (or indexes), the index ought to be an attribute on the 
parser, not the source text.


> If I have a string that stores its index, all of this mess is gone.

What you are describing is covered by Martin Fowler's book 
"Refactoring". He describes the problem:

    A field is, or will be, used by another class more than the 
    class on which it is defined.

and the solution is to move the field from that class to the class where 
it is actually used.

("Refactoring - Ruby Edition", by Jay Fields, Shane Harvie and Martin 
Fowler.)

Having a class (in your case, Source) carry around state which is only 
used by *other functions* is a code-smell. That means that Source is 
responsible for things it has no need of. That's poor design.

By making the parser a class, instead of a bunch of functions, they can 
share state -- the *parser state*. That state includes:

- the text being parsed;
- the tokens that can be found; and
- the position in the text.

The caller can create as many parsers as they need:

parse_this = Parser("some text")
parse_that = Parser("different text")

without them interfering, and then run the parsers independently of each 
other. The implementer, that is you, can change the algorithm used by 
the Parser without the caller needing to know. With your current design, 
you start with this:

# caller is responsible for tracking the index
source = Source("some text")
assert source.i = 0
parse(source)


What happens if next month you decide to change the parsing algorithm? 
Now it needs not one index, but two. You change the parse() function, 
but the caller's code breaks because Source only has one index. You 
can't change Source, because other parts of the code are relying on 
Source having exactly a single index. So you have to introduce *two* new 
pieces of code, and the caller has to make two changes::

source = SourceWithTwoIndexes("some text")
assert source.i = 0 and source.j = -1
improved_parse(source)


Instead, if the parser is responsible for tracking it's own data (the 
index, or indexes), then the caller doesn't need to care if the parsing 
algorithm changes. The internal details of the parser are irrelevant to 
the caller. This is a good thing!

parser = Parse("some text")
parser.parse()

With this design, if you change the internal details of the parser, the 
caller doesn't need to change a thing. They get the improved parser for 
free.

Since the parser tracks both the source text and the index, it doesn't 
need to worry that the Source object might change the index. 

With your design, the index is part of the source text. That means that 
the source text is free to change the index at any time. But it can't do 
that, since there might be a parser in the middle of processing it. So 
the Source class has to carry around data that it isn't free to use.

This is the opposite of encapsulation. It means that the Source object 
and the parsing code are tightly coupled. The Source object has no way 
of knowing whether it is being parsed or not, but has to carry around 
this dead weight, an unused (unused by Source) field, and avoid using it 
for any reason, *just in case* it is being used by a parser. This is the 
very opposite of how OOP is supposed to work.


> It 
> makes for clean and simple interfaces everywhere. Also (one of the 
> consequences) I can directly provide match funcs to the user, instead of 
> having to wrap them inside a func which only utility is to hide the 
> additional index (in both input & output).

I don't quite understand what you mean here. 



-- 
Steven

From eryksun at gmail.com  Thu Jan  2 05:05:47 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 1 Jan 2014 23:05:47 -0500
Subject: [Tutor] Shelve & immutable objects
In-Reply-To: <CAO5ffbbzxdAqqf8dqNiPLq=Tj4c=SZ3Aq3V-oB4WWvsk9ACTGQ@mail.gmail.com>
References: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
 <CAO5ffbYDVEBpq=4twoENLdymCRMuaYxZbotK546a9s4NazzUNw@mail.gmail.com>
 <CAGZAPF4nC+CZtRr=h_TkS_Y=OaXhKOnnBwJ4F-k4yzMfVJzHNg@mail.gmail.com>
 <CAO5ffbbzxdAqqf8dqNiPLq=Tj4c=SZ3Aq3V-oB4WWvsk9ACTGQ@mail.gmail.com>
Message-ID: <CACL+1atVhpcd82TstOVEAhe-pmJCGrr63dLkdYv543w7r_B+2w@mail.gmail.com>

On Wed, Jan 1, 2014 at 11:43 AM, Keith Winston <keithwins at gmail.com> wrote:
> Thanks Danny, I don't understand the re-persisted part, but I'll look into
> it.

Shelf.close calls Shelf.sync to flush the cache. Here's what it does:

    >>> print(inspect.getsource(shelve.Shelf.sync))
        def sync(self):
            if self.writeback and self.cache:
                self.writeback = False
                for key, entry in self.cache.items():
                    self[key] = entry
                self.writeback = True
                self.cache = {}
            if hasattr(self.dict, 'sync'):
                self.dict.sync()

If the writeback cache is enabled, then loading a key also caches the
item in a dict. `sync` writes all of the cached items back and clears
the cache (for which it should be using `self.cache.clear()`).

It also syncs the underlying database if it has a `sync` attribute,
which the gdbm database [1] requires. Per its man page, "gdbm defaults
to no-sync mode" [2]. So actually the "f" flag for opening in fast
mode is obsolete [3].

    1. If you're using a Debian-family Linux, install the
       packages python-gdbm and python3-gdbm.
    2. http://linux.die.net/man/3/gdbm
    3. http://docs.python.org/3/library/dbm#dbm.gnu.open

Have a look at what gets stored in the database. First lets create a
database and add a list:

    >>> import shelve, dbm
    >>> sh = shelve.open('class_shelve')
    >>> sh['alist'] = [1, 2, 3]

You could leave the Shelf open and use its underlying `sh.dict`, but
I'll reopen the database instead:

    >>> sh.close()
    >>> db = dbm.open('class_shelve')
    >>> data = db['alist']
    >>> data
    b'\x80\x03]q\x00(K\x01K\x02K\x03e.'

shelve serialized the list to a byte string with the pickle protocol.
This is a program that instructs the pickle VM to build the list. You
can manually load the list with pickle.loads:

    >>> import pickle
    >>> pickle.loads(data)
    [1, 2, 3]

You can disassemble the pickle with pickletools.dis, if you're curious:

    >>> import pickletools
    >>> pickletools.dis(data)
        0: \x80 PROTO      3
        2: ]    EMPTY_LIST
        3: q    BINPUT     0
        5: (    MARK
        6: K        BININT1    1
        8: K        BININT1    2
       10: K        BININT1    3
       12: e        APPENDS    (MARK at 5)
       13: .    STOP
    highest protocol among opcodes = 2

From denis.spir at gmail.com  Thu Jan  2 10:28:43 2014
From: denis.spir at gmail.com (spir)
Date: Thu, 02 Jan 2014 10:28:43 +0100
Subject: [Tutor] subtyping builtin type
In-Reply-To: <20140102022125.GL29356@ando>
References: <52C2D64B.4060400@gmail.com> <20140101002620.GJ29356@ando>
 <52C41CDD.3000402@gmail.com> <20140102022125.GL29356@ando>
Message-ID: <52C5314B.7050404@gmail.com>

On 01/02/2014 03:21 AM, Steven D'Aprano wrote:
> On Wed, Jan 01, 2014 at 02:49:17PM +0100, spir wrote:
>> On 01/01/2014 01:26 AM, Steven D'Aprano wrote:
>>> On Tue, Dec 31, 2013 at 03:35:55PM +0100, spir wrote:
> [...]
>> I take the opportunity to add a few features, but would do
>> without Source altogether if it were not for 'i'.
>> The reason is: it is for parsing library, or hand-made parsers. Every
>> matching func, representing a pattern (or "rule"), advances in source
>> whenever mathc is ok, right? Thus in addition to return the form (of what
>> was matched), they must return the new match index:
>> 	return (form, i)
>
> The usual way to do this is to make the matching index an attribute of
> the parser, not the text being parsed. In OOP code, you make the parser
> an object:
>
> class Parser:
>      def __init__(self, source):
>          self.current_position = 0  # Always start at the beginning
>          self.source = source
>      def parse(self):
>          ...
>
> parser = Parser("some text to be parsed")
> for token in parser.parse():
>      handle(token)
>
> The index is not an attribute of the source text, because the source
> text doesn't care about the index. Only the parser cares about the
> index, so it should be the responsibility of the parser to manage.

There is (no need for) a distinct Parser class or evne notion of parser. A 
parser is a top-level pattern (rule, object, or match func if one designs more 
like FP than OOP). Symmetrically, every pattern is a parser for what it matches.

Think at branches in a tree: the tree is a top-level branch and every branch is 
a sub-tree.

This conception is not semantically meaningful but highly useful, if not 
necessary, in practice: it permits using every pattern on its own ,for what it 
matches; it permits trying and testing patterns indicidually. (One could always 
find and implement workarounds, they would be needless complications.)

However, I see and partially share what you say -- se below.

>> Symmetrically, every match func using another (meaning nearly all) receive
>> this pair. (Less annoyingly, every math func also takes i as input, in
>> addition to the src str.) (There are also a handful of other annoying
>> points, consequences of those ones.)
>
> The match functions are a property of the parser, not the source text.
> So they should be methods on a Parser object. Since they need to track
> the index (or indexes), the index ought to be an attribute on the
> parser, not the source text.

This does not hold for me. Think eg at 2-phase parsing (like when using lex & 
yacc): the lexer (lex) provides the parser (yacc) with a stream of lexemes 
completely opaquely for the parser, which does not know about indexes (neither 
in original source sting, nore in the stream of lexemes). Since I parse 
(usually) in a single phase, the source string is in the position lex above: it 
feeds the parser with a stream of ucodes, advancing in coherent manner; the 
parser does not need, nore want (lol!) to manage the source's index That's the 
point. The index is a given for the parser, that it just uses to try & match at 
the correct position.

>> If I have a string that stores its index, all of this mess is gone.
>
> What you are describing is covered by Martin Fowler's book
> "Refactoring". He describes the problem:
>
>      A field is, or will be, used by another class more than the
>      class on which it is defined.
>
> and the solution is to move the field from that class to the class where
> it is actually used.
>
> ("Refactoring - Ruby Edition", by Jay Fields, Shane Harvie and Martin
> Fowler.)
>
> Having a class (in your case, Source) carry around state which is only
> used by *other functions* is a code-smell. That means that Source is
> responsible for things it has no need of. That's poor design.

I don't share this. Just like an open file currently beeing read conceptually 
(if not in practice) has a current index.

It's also sane & simple, and thread-safe, even if two Source objects happened to 
share (refs to) the same underlying actual source string (eg read form the same 
source file): each has its own current index.

I don't see how Fowler's views apply to this case. Whether a Source or a Parser 
holds the index does not change attribute access or its wishable properties.

> By making the parser a class, instead of a bunch of functions, they can
> share state -- the *parser state*. That state includes:
>
> - the text being parsed;
> - the tokens that can be found; and
> - the position in the text.
>
> The caller can create as many parsers as they need:
>
> parse_this = Parser("some text")
> parse_that = Parser("different text")
>
> without them interfering, and then run the parsers independently of each
> other. The implementer, that is you, can change the algorithm used by
> the Parser without the caller needing to know. With your current design,
> you start with this:
>
> # caller is responsible for tracking the index
> source = Source("some text")
> assert source.i = 0
> parse(source)

Maybe we just don't have the same experience or practice of parsing, but your 
reflexion does not match (sic!) anything I know. I don't see how having a source 
hold its index prevents anything above, in particular, how does it prevent to 
"change the algorithm used by the Parser without the caller needing to know"?

> What happens if next month you decide to change the parsing algorithm?
> Now it needs not one index, but two.

?
what do you mean?

>  You change the parse() function,
> but the caller's code breaks because Source only has one index.

?
Everyone of us constantly changes the algorithm when in development phase, and 
setting up patterns for a new kind of sources, don't we? What does it have to do 
with where the match index is stored?

>  You
> can't change Source, because other parts of the code are relying on
> Source having exactly a single index.

?

>  So you have to introduce *two* new
> pieces of code, and the caller has to make two changes::
>
> source = SourceWithTwoIndexes("some text")
> assert source.i = 0 and source.j = -1
> improved_parse(source)

???

> Instead, if the parser is responsible for tracking it's own data (the
> index, or indexes), then the caller doesn't need to care if the parsing
> algorithm changes. The internal details of the parser are irrelevant to
> the caller. This is a good thing!

A source is just a source, not part of, container of, or in any way related to 
the parsing algorithm. Changing an algo does not interfere with the source in 
any manner I can imagine.

> parser = Parse("some text")
> parser.parse()
>
> With this design, if you change the internal details of the parser, the
> caller doesn't need to change a thing. They get the improved parser for
> free.
>
> Since the parser tracks both the source text and the index, it doesn't
> need to worry that the Source object might change the index.
>
> With your design, the index is part of the source text. That means that
> the source text is free to change the index at any time. But it can't do
> that, since there might be a parser in the middle of processing it. So
> the Source class has to carry around data that it isn't free to use.
>
> This is the opposite of encapsulation. It means that the Source object
> and the parsing code are tightly coupled. The Source object has no way
> of knowing whether it is being parsed or not, but has to carry around
> this dead weight, an unused (unused by Source) field, and avoid using it
> for any reason, *just in case* it is being used by a parser. This is the
> very opposite of how OOP is supposed to work.

I understand, i guess, the underlying concerns expressed in your views (I 
guess). Like separation of concerns, and things holding their own data. This is 
in fact related to why I want sources to know their index. An alternative is to 
consider the whole library, or parser module (a bunch of matching patterns) as a 
global tool, a parsing machine, and make i a module-level var. Not a global in 
the usual sense, it's really part of the parsing machine (part of the machine's 
state), an attribute thus rather than a plain var. But this prevented beeing 
thread-safe and (how unlikely it may be to ever parse sources in parallel, i 
don't know of any example) this looked somewhat esthetically unsatisfying to me.

The price is having attribute access (in code and execution time) for every 
actual read into the source. I dislike this, but less than having a "lost" var 
roaming around ;-).

>> It
>> makes for clean and simple interfaces everywhere. Also (one of the
>> consequences) I can directly provide match funcs to the user, instead of
>> having to wrap them inside a func which only utility is to hide the
>> additional index (in both input & output).
>
> I don't quite understand what you mean here.

If every match func, or 'match' method of pattern objects, takes & returns the 
index (in addition to their source input and form output), then they don't have 
the simple & expected interface by users of the tool (lib or hand-backed parser, 
or a mix). You want to write this
	form = pat.match(source)
Not that:
	form, i = pat.match(source, i)

I'd thus need to provide wrapper funcs to get rid of i in both input and output.

Denis

From keithwins at gmail.com  Thu Jan  2 10:15:06 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 2 Jan 2014 04:15:06 -0500
Subject: [Tutor] Shelve & immutable objects
In-Reply-To: <CACL+1atVhpcd82TstOVEAhe-pmJCGrr63dLkdYv543w7r_B+2w@mail.gmail.com>
References: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
 <CAO5ffbYDVEBpq=4twoENLdymCRMuaYxZbotK546a9s4NazzUNw@mail.gmail.com>
 <CAGZAPF4nC+CZtRr=h_TkS_Y=OaXhKOnnBwJ4F-k4yzMfVJzHNg@mail.gmail.com>
 <CAO5ffbbzxdAqqf8dqNiPLq=Tj4c=SZ3Aq3V-oB4WWvsk9ACTGQ@mail.gmail.com>
 <CACL+1atVhpcd82TstOVEAhe-pmJCGrr63dLkdYv543w7r_B+2w@mail.gmail.com>
Message-ID: <CAO5ffbb-qUkJrhKRNDUcb9W-LtsjK1_t5C=H0UM=Jz9VZ3m-hQ@mail.gmail.com>

Thanks for all this Eryksun (and Mark!), but... I don't understand why you
brought gdbm in? Is it something underlying shelve, or a better approach,
or something else? That last part really puts me in a pickle, and I don't
understand why.

Separately, I'm also curious about how to process big files. For example, I
was trying to play 100 million games of chutes & ladders, and I crashed my
machine, I believe: the game results, including 4 ints & 2 short lists of
ints per game, are gathered into a list, so it can become a pretty big
list. I need to do stats and other analyses on it in the end (okay, I
really don't NEED to play 100 million games of chutes & ladders, but as
long as I have...): I suppose I could break it into manageable (maybe 1
million games each), but that will make some of the stats either clunky or
wrong (I haven't really attacked that part yet).

And since I'm not REALLY ready to ask this question, I'll tack it on to the
end... I'm also beginning to think about how to speed it up: I'm imagining
my two options are going to be to code some sections in a faster language
(i.e. C), or maybe to introduce multi-threading since I'm working on a
multicore machine generally (core I7), and I'm doing a lot of iterations of
the same thing with no important order... seems like a good candidate. Now,
I'm probably pretty far from that piece (in my learning process), but this
is moving along pretty well so I'm open to suggestions about how to
proceed. I've started switching up my code a fair bit to try to make it
more OOP, though I'm still rough on that part.

K
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140102/52783543/attachment.html>

From denis.spir at gmail.com  Thu Jan  2 11:12:30 2014
From: denis.spir at gmail.com (spir)
Date: Thu, 02 Jan 2014 11:12:30 +0100
Subject: [Tutor] what's your name? (to a class)
Message-ID: <52C53B8E.1040906@gmail.com>

Hello tutorians,

Am I missing something or don't classes know how they're called (unlike funcs, 
which have a __name__ attribute, very practicle)? Is there a way to get it 
otherwise?

The point is to have a super-type define a general __repr__ like eg:

class SuperType:
     # ...
     def __repr__ (sef):
         return "%s(stuff)" % (self.__class__.__name__, stuff)

But I need each class to know its name. Subtypes are actually defined by users 
(of a lib), presently they are forced to write the name explicitely, which is 
stupid since they already give it as var name:

class SubType (SuperType):
     __name__ = "SubType"
     # ....

Denis

From nik at naturalnet.de  Thu Jan  2 11:18:22 2014
From: nik at naturalnet.de (Dominik George)
Date: Thu, 2 Jan 2014 11:18:22 +0100
Subject: [Tutor] what's your name? (to a class)
In-Reply-To: <52C53B8E.1040906@gmail.com>
References: <52C53B8E.1040906@gmail.com>
Message-ID: <20140102101822.GA6736@keks.naturalnet.de>

Hi,

> Am I missing something or don't classes know how they're called
> (unlike funcs, which have a __name__ attribute, very practicle)? Is
> there a way to get it otherwise?

The class has it, the instance doesn't. That said, you are looking for self.__class__.__name__ ...

> class SuperType:
>     # ...
>     def __repr__ (sef):
>         return "%s(stuff)" % (self.__class__.__name__, stuff)

... which you do use here.

> But I need each class to know its name. Subtypes are actually
> defined by users (of a lib), presently they are forced to write the
> name explicitely, which is stupid since they already give it as var
> name:
> 
> class SubType (SuperType):
>     __name__ = "SubType"
>     # ....

I do not get it. The __class__.__name__ thing works great for me:

  >>> class Foo():
  ...     def whoami(self):
  ...         return self.__class__.__name__
  ...
  >>> f = Foo()
  >>> f.whoami()
  'Foo'
  >>> class Bar(Foo):
  ...     pass
  ... 
  >>> b = Bar()
  >>> b.whoami()
  'Bar'

Please be a bit more specific about your problem, because the problem
you described obviously does not exist ;).

-nik

-- 
* mirabilos is handling my post-1990 smartphone *
<mirabilos> Aaah, it vibrates! Wherefore art thou, demonic device??

PGP-Fingerprint: 3C9D 54A4 7575 C026 FB17  FD26 B79A 3C16 A0C4 F296
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 905 bytes
Desc: Digital signature
URL: <http://mail.python.org/pipermail/tutor/attachments/20140102/c6089590/attachment-0001.sig>

From steve at pearwood.info  Thu Jan  2 14:40:23 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 3 Jan 2014 00:40:23 +1100
Subject: [Tutor] what's your name? (to a class)
In-Reply-To: <52C53B8E.1040906@gmail.com>
References: <52C53B8E.1040906@gmail.com>
Message-ID: <20140102134023.GN29356@ando>

On Thu, Jan 02, 2014 at 11:12:30AM +0100, spir wrote:
> Hello tutorians,
> 
> Am I missing something or don't classes know how they're called (unlike 
> funcs, which have a __name__ attribute, very practicle)? Is there a way to 
> get it otherwise?

py> type(42).__name__
'int'
py> class Spam:
...     pass
...
py> Spam.__name__
'Spam'

 
> The point is to have a super-type define a general __repr__ like eg:
> 
> class SuperType:
>     # ...
>     def __repr__ (sef):
>         return "%s(stuff)" % (self.__class__.__name__, stuff)

That works for me. Is there some reason you think it doesn't work?


> But I need each class to know its name. Subtypes are actually defined by 
> users (of a lib), presently they are forced to write the name explicitely, 
> which is stupid since they already give it as var name:
> 
> class SubType (SuperType):
>     __name__ = "SubType"

Completely unnecessary.

py> class Ham(Spam):
...     pass
...
py> Ham.__name__
'Ham'


I think maybe you've made an error somewhere and are misinterpreting 
what you are seeing.



-- 
Steven

From steve at pearwood.info  Thu Jan  2 15:29:58 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 3 Jan 2014 01:29:58 +1100
Subject: [Tutor] Shelve & immutable objects
In-Reply-To: <CAO5ffbb-qUkJrhKRNDUcb9W-LtsjK1_t5C=H0UM=Jz9VZ3m-hQ@mail.gmail.com>
References: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
 <CAO5ffbYDVEBpq=4twoENLdymCRMuaYxZbotK546a9s4NazzUNw@mail.gmail.com>
 <CAGZAPF4nC+CZtRr=h_TkS_Y=OaXhKOnnBwJ4F-k4yzMfVJzHNg@mail.gmail.com>
 <CAO5ffbbzxdAqqf8dqNiPLq=Tj4c=SZ3Aq3V-oB4WWvsk9ACTGQ@mail.gmail.com>
 <CACL+1atVhpcd82TstOVEAhe-pmJCGrr63dLkdYv543w7r_B+2w@mail.gmail.com>
 <CAO5ffbb-qUkJrhKRNDUcb9W-LtsjK1_t5C=H0UM=Jz9VZ3m-hQ@mail.gmail.com>
Message-ID: <20140102142957.GO29356@ando>

On Thu, Jan 02, 2014 at 04:15:06AM -0500, Keith Winston wrote:

> Separately, I'm also curious about how to process big files. For example, I
> was trying to play 100 million games of chutes & ladders, and I crashed my
> machine, I believe: the game results, including 4 ints & 2 short lists of
> ints per game, are gathered into a list, so it can become a pretty big
> list. 

How to process big files, in order of "best" to "worst" (in my opinion):

(1) Get more memory.

(2) Find a way to process them in small chunks, e.g. a line at a time, 
rather than try to hold the entire file in memory at once.

(3) Split them into small files, then process each file in turn.

(4) Pass them to external tools which are optimized for dealing with 
huge files.

(5) Find a way to process them using mmap.

(6) Write your own tool for handling huge files.


> I need to do stats and other analyses on it in the end (okay, I
> really don't NEED to play 100 million games of chutes & ladders, but as
> long as I have...): I suppose I could break it into manageable (maybe 1
> million games each), but that will make some of the stats either clunky or
> wrong (I haven't really attacked that part yet).

It shouldn't. Well, it might, but only if you're doing some pretty 
sophisticated statistical analysis. Most common statistics can be 
calculated on a single pass through the data. If you need to calculate 
(say) the mean, variance and standard deviation, it is moderately 
straight forward to calculate all three in a single pass without needing 
to have all the data in memory at once.

(Feel free to ask for more detail if you wish.)

Even statistics like median, which normally requires the entire data set 
to be in memory so it can be sorted, can be calculated with a couple of 
passes through the data. I think there is even a single pass algorithm 
for it.


> And since I'm not REALLY ready to ask this question, I'll tack it on to the
> end... I'm also beginning to think about how to speed it up: I'm imagining
> my two options are going to be to code some sections in a faster language
> (i.e. C), or maybe to introduce multi-threading since I'm working on a
> multicore machine generally (core I7), and I'm doing a lot of iterations of
> the same thing with no important order... seems like a good candidate.

A game of Chutes and Ladders (or as we call it in Australia, Snakes 
and Ladders) surely doesn't need to be optimized. It will spend most of 
its time waiting for the human user, who is probably a hundred thousand 
or million times slower than the computer.

But let's say you want to make it faster regardless. How to make it 
faster:

(1) Use a smarter algorithm or less wasteful implementation.

(2) Get more memory.

(3) Get a faster computer.

(4) I think what you are trying to do is a good candidate for PyPy, the 
optimizing Python JIT compiler. Especially if you are playing multiple 
millions of games.

(5) Profile, profile, profile, profile.

Only once you have profiled your code can you possibly hope to guess 
where the bottlenecks are. After 15 or 20 years of programming with 
Python, my guesses for the bottlenecks are still wrong more often than 
they are right.

Assuming you identify the actual bottlenecks:

(6) Try writing them in Cython, which will often give you good speedups.

(7) Or write a C extension.

Should you use threads? Probably not.

- Unless the bottleneck in your code is disk or network I/O, 
  threads will not help, they'll just make your program slower.

- Unless you use IronPython or Jython instead, in which case 
  treads *might* help. But probably not as much as you think.

- If your bottleneck is CPU processing, you can use the 
  multiprocessing module instead of threads.

- You did profile your code first didn't you?


> Now,
> I'm probably pretty far from that piece (in my learning process), but this
> is moving along pretty well so I'm open to suggestions about how to
> proceed. I've started switching up my code a fair bit to try to make it
> more OOP, though I'm still rough on that part.


Advice about optimization from some experts:

http://en.wikipedia.org/wiki/Program_optimization#Quotes

My favourite quote is:

    The First Rule of Program Optimization: 
        Don't do it. 

    The Second Rule of Program Optimization (for experts only!): 
        Don't do it yet.



-- 
Steven

From eryksun at gmail.com  Thu Jan  2 16:48:24 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 2 Jan 2014 10:48:24 -0500
Subject: [Tutor] what's your name? (to a class)
In-Reply-To: <52C53B8E.1040906@gmail.com>
References: <52C53B8E.1040906@gmail.com>
Message-ID: <CACL+1at=y4yfeTBOE2MYzUkpzQruf=8PE6R9HmmLe+3i9gduWw@mail.gmail.com>

On Thu, Jan 2, 2014 at 5:12 AM, spir <denis.spir at gmail.com> wrote:
>
> Am I missing something or don't classes know how they're called (unlike
> funcs, which have a __name__ attribute, very practicle)? Is there a way to
> get it otherwise?

What are you smoking, and where can I get some? ;)

Actually, I think I understand the source of your confusion. `dir`
doesn't show attributes from the metaclass because that would be too
confusing.

__class__ is a descriptor in the dict of `type`:

    >>> name = vars(type)['__name__']
    >>> type(name)
    <class 'getset_descriptor'>

    >>> class C: pass
    ...
    >>> name.__get__(C)
    'C'

For a heap type, the getter can just return the Python object
`ht_name`. For a built-in type it has to construct a Unicode string
(assuming 3.x) from the `tp_name` slot.

The setter (`type_set_name`) won't let you change the name of a
built-in type. It also has to ensure that the name doesn't contain a
null:

    >>> name.__set__(C, 'GoodName')
    >>> C.__name__
    'GoodName'

    >>> name.__set__(int, 'float')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: can't set int.__name__

    >>> name.__set__(C, 'Bad\x00Name')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: __name__ must not contain null bytes

    >>> name.__set__(C, 'Really Weird Name')
    >>> C.__name__
    'Really Weird Name'

From eryksun at gmail.com  Thu Jan  2 16:53:49 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 2 Jan 2014 10:53:49 -0500
Subject: [Tutor] what's your name? (to a class)
In-Reply-To: <CACL+1at=y4yfeTBOE2MYzUkpzQruf=8PE6R9HmmLe+3i9gduWw@mail.gmail.com>
References: <52C53B8E.1040906@gmail.com>
 <CACL+1at=y4yfeTBOE2MYzUkpzQruf=8PE6R9HmmLe+3i9gduWw@mail.gmail.com>
Message-ID: <CACL+1avJeO9hrhvo2shY0rjLEH_Kmu0fmydV2Ek-GL3LKg8qoQ@mail.gmail.com>

On Thu, Jan 2, 2014 at 10:48 AM, eryksun <eryksun at gmail.com> wrote:
> __class__ is a descriptor in the dict of `type`:

I think I must be smoking something, too. That should be __name__. Sorry.

From eryksun at gmail.com  Thu Jan  2 17:00:46 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 2 Jan 2014 11:00:46 -0500
Subject: [Tutor] Shelve & immutable objects
In-Reply-To: <CAO5ffbb-qUkJrhKRNDUcb9W-LtsjK1_t5C=H0UM=Jz9VZ3m-hQ@mail.gmail.com>
References: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
 <CAO5ffbYDVEBpq=4twoENLdymCRMuaYxZbotK546a9s4NazzUNw@mail.gmail.com>
 <CAGZAPF4nC+CZtRr=h_TkS_Y=OaXhKOnnBwJ4F-k4yzMfVJzHNg@mail.gmail.com>
 <CAO5ffbbzxdAqqf8dqNiPLq=Tj4c=SZ3Aq3V-oB4WWvsk9ACTGQ@mail.gmail.com>
 <CACL+1atVhpcd82TstOVEAhe-pmJCGrr63dLkdYv543w7r_B+2w@mail.gmail.com>
 <CAO5ffbb-qUkJrhKRNDUcb9W-LtsjK1_t5C=H0UM=Jz9VZ3m-hQ@mail.gmail.com>
Message-ID: <CACL+1atBP67pGx+jnHCLUggKGyN-Fbc34hLY4dRt0ju=PEzaaw@mail.gmail.com>

On Thu, Jan 2, 2014 at 4:15 AM, Keith Winston <keithwins at gmail.com> wrote:
> Thanks for all this Eryksun (and Mark!), but... I don't understand why you
> brought gdbm in? Is it something underlying shelve, or a better approach, or
> something else? That last part really puts me in a pickle, and I don't
> understand why.

A Shelf is backed by a container with the following mapping methods:

    keys
    __contains__
    __getitem__
    __setitem__
    __delitem__
    __len__

Shelf will also try to call `close` and `sync` on the container if
available. For some reason no one has made Shelf into a context
manager (i.e. __enter__ and __exit__), so remember to close() it.

For demonstration purposes, you can use a dict with Shelf:

    >>> sh = shelve.Shelf(dict={})
    >>> sh['alist'] = [1,2,3]

The mapping is referenced in the (badly named) `dict` attribute:

    >>> sh.dict
    {b'alist': b'\x80\x03]q\x00(K\x01K\x02K\x03e.'}

Keys are encoded as bytes (UTF-8 default) and the value is serialized
using pickle. This is to support using a database from the dbm module.

shelve.open returns an instance of shelve.DbfilenameShelf, which is a
subclass of Shelf specialized to open a dbm database.

Here's an overview of Unix dbm databases that Google turned up:

http://www.unixpapa.com/incnote/dbm.html

Note the size restrictions for keys and values in ndbm, which gdbm
doesn't have. Using gdbm lifts the restriction on the size of pickled
objects (the docs vaguely suggest to keep them "fairly small").
Unfortunately gdbm isn't always available.

On my system, dbm defaults to creating a _gdbm.gdbm database, where
_gdbm is an extension module that wraps the GNU gdbm library (e.g.
libgdbm.so.3).

You can use a different database with Shelf (or a subclass), so long
as it has the required methods. For example, shelve.BsdDbShelf is
available for use with pybsddb (Debian package "python3-bsddb3"). It
exposes the bsddb3 database methods `first`, `next`, `previous`,
`last` and `set_location`.

> Separately, I'm also curious about how to process big files.
> ...
> I'm also beginning to think about how to speed it up:

I defer to Steven's sage advice.

Look into using databases such as sqlite3, numpy, and also add the
multiprocessing and concurrent.futures modules to your todo list. Even
if you know C/C++, I suggest you use Cython to create CPython
extension modules.

http://www.cython.org

From denis.spir at gmail.com  Thu Jan  2 17:18:04 2014
From: denis.spir at gmail.com (spir)
Date: Thu, 02 Jan 2014 17:18:04 +0100
Subject: [Tutor] what's your name? (to a class)
In-Reply-To: <20140102101822.GA6736@keks.naturalnet.de>
References: <52C53B8E.1040906@gmail.com>
 <20140102101822.GA6736@keks.naturalnet.de>
Message-ID: <52C5913C.4090001@gmail.com>

On 01/02/2014 11:18 AM, Dominik George wrote:
> Hi,
>
>> Am I missing something or don't classes know how they're called
>> (unlike funcs, which have a __name__ attribute, very practicle)? Is
>> there a way to get it otherwise?
>
> The class has it, the instance doesn't. That said, you are looking for self.__class__.__name__ ...
>
>> class SuperType:
>>      # ...
>>      def __repr__ (sef):
>>          return "%s(stuff)" % (self.__class__.__name__, stuff)
>
> ... which you do use here.

Well, this was not real code, but an example of what I wished to be able to write!

>> But I need each class to know its name. Subtypes are actually
>> defined by users (of a lib), presently they are forced to write the
>> name explicitely, which is stupid since they already give it as var
>> name:
>>
>> class SubType (SuperType):
>>      __name__ = "SubType"
>>      # ....
>
> I do not get it. The __class__.__name__ thing works great for me:
>
>    >>> class Foo():
>    ...     def whoami(self):
>    ...         return self.__class__.__name__
>    ...
>    >>> f = Foo()
>    >>> f.whoami()
>    'Foo'
>    >>> class Bar(Foo):
>    ...     pass
>    ...
>    >>> b = Bar()
>    >>> b.whoami()
>    'Bar'
>
> Please be a bit more specific about your problem, because the problem
> you described obviously does not exist ;).

I just missed it. Sorry!
In fact, I did:

>>> class C: pass
...
>>> dir(C)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', 
'__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', 
'__subclasshook__', '__weakref__']

No __name__, or am I blind? But:

>>> C.__name__
'C'

Still, there is a __name__.
???


Compare with:

>>> def f(): pass
...
>>> dir(f)
['__annotations__', '__call__', '__class__', '__closure__', '__code__', 
'__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', 
'__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', 
'__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', 
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

Here I can see __name__ (thus, I'm probably not that blind yet ;-).

Denis


From denis.spir at gmail.com  Thu Jan  2 17:21:46 2014
From: denis.spir at gmail.com (spir)
Date: Thu, 02 Jan 2014 17:21:46 +0100
Subject: [Tutor] what's your name? (to a class)
In-Reply-To: <20140102134023.GN29356@ando>
References: <52C53B8E.1040906@gmail.com> <20140102134023.GN29356@ando>
Message-ID: <52C5921A.4050904@gmail.com>

On 01/02/2014 02:40 PM, Steven D'Aprano wrote:
> On Thu, Jan 02, 2014 at 11:12:30AM +0100, spir wrote:
>> Hello tutorians,
>>
>> Am I missing something or don't classes know how they're called (unlike
>> funcs, which have a __name__ attribute, very practicle)? Is there a way to
>> get it otherwise?
>
> py> type(42).__name__
> 'int'
> py> class Spam:
> ...     pass
> ...
> py> Spam.__name__
> 'Spam'
>
>
>> The point is to have a super-type define a general __repr__ like eg:
>>
>> class SuperType:
>>      # ...
>>      def __repr__ (sef):
>>          return "%s(stuff)" % (self.__class__.__name__, stuff)
>
> That works for me. Is there some reason you think it doesn't work?

Sorry again, the reason is dir() does not show __name__ for classes, while it 
does for funcs. See answer to Dominik. I guess I've now found it:

>>> class C: pass
...
>>> dir(C) 		# note __dir__ below:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', 
'__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', 
'__subclasshook__', '__weakref__']
>>> dir(C.__dir__)	# here is __name__ :
['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__get__', '__getattribute__', '__gt__', '__hash__', 
'__init__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__objclass__', 
'__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__sizeof__', '__str__', '__subclasshook__']

Denis

From denis.spir at gmail.com  Thu Jan  2 17:26:04 2014
From: denis.spir at gmail.com (spir)
Date: Thu, 02 Jan 2014 17:26:04 +0100
Subject: [Tutor] what's your name? (to a class)
In-Reply-To: <CACL+1at=y4yfeTBOE2MYzUkpzQruf=8PE6R9HmmLe+3i9gduWw@mail.gmail.com>
References: <52C53B8E.1040906@gmail.com>
 <CACL+1at=y4yfeTBOE2MYzUkpzQruf=8PE6R9HmmLe+3i9gduWw@mail.gmail.com>
Message-ID: <52C5931C.30007@gmail.com>

On 01/02/2014 04:48 PM, eryksun wrote:
> On Thu, Jan 2, 2014 at 5:12 AM, spir <denis.spir at gmail.com> wrote:
>>
>> Am I missing something or don't classes know how they're called (unlike
>> funcs, which have a __name__ attribute, very practicle)? Is there a way to
>> get it otherwise?
>
> What are you smoking, and where can I get some? ;)

I hadn't this morminig ;-)
Must be getting along with wonderful people these times, makes similar effects 
on mood, without side-effects (as fonctional programmers say ;-) ...

> Actually, I think I understand the source of your confusion. `dir`
> doesn't show attributes from the metaclass because that would be too
> confusing.

That's it, exactly! (see other replies)


From dyoo at hashcollision.org  Thu Jan  2 18:21:38 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Thu, 2 Jan 2014 09:21:38 -0800
Subject: [Tutor] Shelve & immutable objects
In-Reply-To: <CAO5ffbb-qUkJrhKRNDUcb9W-LtsjK1_t5C=H0UM=Jz9VZ3m-hQ@mail.gmail.com>
References: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
 <CAO5ffbYDVEBpq=4twoENLdymCRMuaYxZbotK546a9s4NazzUNw@mail.gmail.com>
 <CAGZAPF4nC+CZtRr=h_TkS_Y=OaXhKOnnBwJ4F-k4yzMfVJzHNg@mail.gmail.com>
 <CAO5ffbbzxdAqqf8dqNiPLq=Tj4c=SZ3Aq3V-oB4WWvsk9ACTGQ@mail.gmail.com>
 <CACL+1atVhpcd82TstOVEAhe-pmJCGrr63dLkdYv543w7r_B+2w@mail.gmail.com>
 <CAO5ffbb-qUkJrhKRNDUcb9W-LtsjK1_t5C=H0UM=Jz9VZ3m-hQ@mail.gmail.com>
Message-ID: <CAGZAPF5TVbQWS9t23BcnfA+=_KbCmOY3V1GFjcQjsMOpbaYsyg@mail.gmail.com>

> Separately, I'm also curious about how to process big files. For example, I
> was trying to play 100 million games of chutes & ladders, and I crashed my
> machine, I believe: the game results, including 4 ints & 2 short lists of
> ints per game, are gathered into a list, so it can become a pretty big list.
> I need to do stats and other analyses on it in the end (okay, I really don't
> NEED to play 100 million games of chutes & ladders, but as long as I
> have...): I suppose I could break it into manageable (maybe 1 million games
> each), but that will make some of the stats either clunky or wrong (I
> haven't really attacked that part yet).

This is probably one of those cases where you don't want to persist
this in active memory, but rather store it in some kind of long-term
store.

We can do a back of the envelope calculation to see why.  An int's
native size is 4 bytes on 32-bit machines.  This is Python, so there's
a bit more overhead.  Let's roughly say that each record about 10
ints, so about 40 bytes.

    100 * 10^6 records * 40 bytes per record = 4 * 10^9 bytes.

###############################
>>> import humanize
>>> humanize.intword(4*10**9)
'4 billion'
###############################

So that's about 4 billion bytes, as a very rough guess.

Unfortunately, when we get to those magnitudes, that's way too large
to fit into a standard computer's memory.  32-bit machines can only
address up to about 4 billion bytes:

################################
>>> humanize.intword(2**32)
'4.3 billion'
################################

So trying to juggle all those records in short-term RAM is a
non-starter: it won't work.  We'll want to do something different
instead, such as saving each record into a persistent on-disk,
external database.

If you're interested, bring this up as a separate topic on
python-tutor, and I'm sure folks here will be happy to talk about it.


Good luck!

From eryksun at gmail.com  Thu Jan  2 18:40:24 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 2 Jan 2014 12:40:24 -0500
Subject: [Tutor] what's your name? (to a class)
In-Reply-To: <52C5921A.4050904@gmail.com>
References: <52C53B8E.1040906@gmail.com> <20140102134023.GN29356@ando>
 <52C5921A.4050904@gmail.com>
Message-ID: <CACL+1auM5BnvaAd=q+SiEODd6Bm0-kyPH9NSJZ-jFYfJP8mq7A@mail.gmail.com>

On Thu, Jan 2, 2014 at 11:21 AM, spir <denis.spir at gmail.com> wrote:
> dir(C.__dir__)  # here is __name__ :

It's good that you've brought up the special method __dir__, because
that's at the heart of the issue. In 3.3, objects use object.__dir__
unless the type overrides it:

    >>> vars(object)['__dir__']
    <method '__dir__' of 'object' objects>

    >>> vars(type)['__dir__']
    <method '__dir__' of 'type' objects>

Your class C is an instance of `type`. Here's the comment for
`type_dir` in typeobject.c:

    __dir__ for type objects: returns __dict__ and __bases__.
    We deliberately don't suck up its __class__, as methods
    belonging to the metaclass would probably be more
    confusing than helpful.

Also, there's a note about this in the docs:

http://docs.python.org/3/library/functions.html#dir

    Because dir() is supplied primarily as a convenience for
    use at an interactive prompt, it tries to supply an
    interesting set of names more than it tries to supply a
    rigorously or consistently defined set of names, and
    its detailed behavior may change across releases. For
    example, metaclass attributes are not in the result
    list when the argument is a class.

Prior to 3.3 (see issue 12166), there's no type.__dir__ or
object.__dir__ built-in methods, so this behavior is baked in.

http://bugs.python.org/issue12166

Back to __name__, for a built-in type the getter decodes the UTF-8
byte string in the `tp_name` slot. It's an example of why you should
rarely depend on identity checks as opposed to equality. You might be
lulled into complacency by how it works for heap types:

    >>> name1 = C.__name__
    >>> name2 = C.__name__
    >>> name1 is name2
    True

But there's a built-in surprise:

    >>> name1 = type.__name__
    >>> name2 = type.__name__
    >>> name1 is name2
    False

For non-class objects, the rules vary with the type. For a built-in
method, the name is created on the fly from the `ml_name` field of its
`PyMethodDef`. There's no setter, so it's readonly. For a function
object, you can only set the name to a string and you can't delete it.
But you can set it to a name with a null in it since it doesn't need
compatibility with a C null-terminated string:

    >>> f = lambda:0
    >>> f.__name__ = '\x00'
    >>> f.__name__
    '\x00'

From dwightdhutto at gmail.com  Thu Jan  2 19:34:29 2014
From: dwightdhutto at gmail.com (David Hutto)
Date: Thu, 2 Jan 2014 13:34:29 -0500
Subject: [Tutor] Shelve & immutable objects
In-Reply-To: <CAGZAPF5TVbQWS9t23BcnfA+=_KbCmOY3V1GFjcQjsMOpbaYsyg@mail.gmail.com>
References: <CAO5ffbY4_9Tackt05paJMd4+vtDufYaiGq9QvQeLie=xp1O=7w@mail.gmail.com>
 <CAO5ffbYDVEBpq=4twoENLdymCRMuaYxZbotK546a9s4NazzUNw@mail.gmail.com>
 <CAGZAPF4nC+CZtRr=h_TkS_Y=OaXhKOnnBwJ4F-k4yzMfVJzHNg@mail.gmail.com>
 <CAO5ffbbzxdAqqf8dqNiPLq=Tj4c=SZ3Aq3V-oB4WWvsk9ACTGQ@mail.gmail.com>
 <CACL+1atVhpcd82TstOVEAhe-pmJCGrr63dLkdYv543w7r_B+2w@mail.gmail.com>
 <CAO5ffbb-qUkJrhKRNDUcb9W-LtsjK1_t5C=H0UM=Jz9VZ3m-hQ@mail.gmail.com>
 <CAGZAPF5TVbQWS9t23BcnfA+=_KbCmOY3V1GFjcQjsMOpbaYsyg@mail.gmail.com>
Message-ID: <CA+vVgJV9H7U0M4ybmf7AHYzC_+xrd0ZvbpME7t4ykf92=0Q8Mw@mail.gmail.com>

> Separately, I'm also curious about how to process big files. For example,
I
> was trying to play 100 million games of chutes & ladders

Without doing the 100,000,000, you could try either researching the nums,
or trying an algorithm that tried intervals, and narrowed down the best ,
and numerically decisive amount of largest intervals of chute and ladders..
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140102/2663a0a3/attachment.html>

From chigga101 at gmail.com  Fri Jan  3 03:17:56 2014
From: chigga101 at gmail.com (Matthew Ngaha)
Date: Fri, 3 Jan 2014 02:17:56 +0000
Subject: [Tutor] sqlite3 import problem
Message-ID: <CACzNyA3vqHNV985m+gaePZ8Z3H-HM9cuzUMjKA_GKjGjidTwOQ@mail.gmail.com>

im having problems importing sqlite3 on ubuntu python3.

  File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in <module>
    from sqlite3.dbapi2 import *
  File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in <module>
    from _sqlite3 import *
ImportError: No module named '_sqlite3'

i have that path and file (dbapi2.py). the problem is an import
statement for _sqlite3. i don't see this file but shouldn't python3.3
be able to import sqlite without errors? any suggestions? does anyone
have _sqlite3.py in their   /usr/local/lib/python3.3/sqlite3/
directory?

From dyoo at hashcollision.org  Fri Jan  3 04:00:29 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Thu, 2 Jan 2014 19:00:29 -0800
Subject: [Tutor] sqlite3 import problem
In-Reply-To: <CACzNyA3vqHNV985m+gaePZ8Z3H-HM9cuzUMjKA_GKjGjidTwOQ@mail.gmail.com>
References: <CACzNyA3vqHNV985m+gaePZ8Z3H-HM9cuzUMjKA_GKjGjidTwOQ@mail.gmail.com>
Message-ID: <CAGZAPF6Dj6PtAircYKN+EXYjW+Ptc2RMiQ09ozayhKp43wmVGg@mail.gmail.com>

Hi Matthew,

This might be an Ubuntu bug or deficiency.


The file you're looking for is for the underlying low-level C module
that bridges the world of SQLite and Python.  By all rights, this
would have been provided by something like the "python-pysqlite2"
package, but that package is for Python 2.


I have not been able yet to find the equivalent binary package for
Python 3, out of the list in:

    http://packages.debian.org/search?keywords=python3

and that seems unfortunate.  Does anyone with Ubuntu experience know
more information about this?


>From discussion on Stack Overflow, I see that people have been able to
compile Python 3 from scratch and things work:

    http://stackoverflow.com/questions/8628774/python-3-2-cant-import-sqlite3-module
    http://superuser.com/questions/557152/sqlite-not-available-with-python-3-3-0-on-debian

Frankly, that seems somewhat overkill for the situation, but if you
really have to, that's one workaround.  It certainly sounds a bit
funky: is there something that stops the package developer from having
some 'python3-pysqlite2' package?  I'm very confused.


I'd recommend asking on an Ubuntu-related forum to confirm that this
is an Ubuntu or Debian problem, and then hopefully they'll be able to
point you in the right direction or get the gears moving to fix this.

From keithwins at gmail.com  Fri Jan  3 06:22:17 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 00:22:17 -0500
Subject: [Tutor] What's in a name?
Message-ID: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>

I've got the beginner's version of a question I think Denis asked
recently...

If I'm iterating a variable through a series of list names, for future
processing, I would like to print the name of the list the variable is set
to in a given moment... i.e.

for i in [alist, blist, clist]
    i[3] = "okey dokey "
    print(i[3], i.name)  # this is definitely not the way to do it...

output:
okey dokey alist
okey dokey blist
okey dokey clist

Is there any way to do that? I'm thinking there may not be, since the
variable is actually bound to the content of the list, not the other
name... which would be good, in the sense that I'm beginning to understand,
but bad in the sense that I need to rethink a piece (or two) of code.
-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/f002cec8/attachment.html>

From keithwins at gmail.com  Fri Jan  3 06:29:34 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 00:29:34 -0500
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
Message-ID: <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>

Hmm, maybe I stumbled upon at least one approach, turning the problem
around. Make it something like:

for i in ["alist", "blist", "clist"]
    i[3] = "okey dokey "
    print(eval(i)[3], i)

Of course I've been staring at this for a while, but as soon as I post I
find a way... this is my first use of eval(), so it took me a while to
stumble upon it. If there are more elegant solutions, I'm all ears.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/35f5d991/attachment.html>

From breamoreboy at yahoo.co.uk  Fri Jan  3 06:40:54 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Fri, 03 Jan 2014 05:40:54 +0000
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
Message-ID: <la5ifu$1b1$1@ger.gmane.org>

On 03/01/2014 05:22, Keith Winston wrote:
> I've got the beginner's version of a question I think Denis asked
> recently...
>
> If I'm iterating a variable through a series of list names, for future
> processing, I would like to print the name of the list the variable is
> set to in a given moment... i.e.
>
> for i in [alist, blist, clist]
>      i[3] = "okey dokey "
>      print(i[3], i.name <http://i.name>)  # this is definitely not the
> way to do it...
>
> output:
> okey dokey alist
> okey dokey blist
> okey dokey clist
>
> Is there any way to do that? I'm thinking there may not be, since the
> variable is actually bound to the content of the list, not the other
> name... which would be good, in the sense that I'm beginning to
> understand, but bad in the sense that I need to rethink a piece (or two)
> of code.
> --
> Keith
>

I don't understand what you're asking for.  It doesn't help that the 
code you've posted isn't even valid.  If you add the missing colon at 
the end of the for loop, you've still got a problem in that standard 
lists don't have a name attribute.

-- 
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  Fri Jan  3 06:51:29 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Fri, 03 Jan 2014 05:51:29 +0000
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
Message-ID: <la5j3p$76k$1@ger.gmane.org>

On 03/01/2014 05:29, Keith Winston wrote:
> Hmm, maybe I stumbled upon at least one approach, turning the problem
> around. Make it something like:
>
> for i in ["alist", "blist", "clist"]
>      i[3] = "okey dokey "
>      print(eval(i)[3], i)
>
> Of course I've been staring at this for a while, but as soon as I post I
> find a way... this is my first use of eval(), so it took me a while to
> stumble upon it. If there are more elegant solutions, I'm all ears.
>

Your code is still invalid.  I still don't understand what you're asking 
for.  I've never used eval in over 10 years of using Python, here's why 
http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html

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

Mark Lawrence


From dyoo at hashcollision.org  Fri Jan  3 06:57:20 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Thu, 2 Jan 2014 21:57:20 -0800
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
Message-ID: <CAGZAPF4hpBfGH-yCg-+RfedPTA8OQOTK6f9SmQsawDWPs6h08A@mail.gmail.com>

On Thu, Jan 2, 2014 at 9:22 PM, Keith Winston <keithwins at gmail.com> wrote:
> I've got the beginner's version of a question I think Denis asked
> recently...
>
> If I'm iterating a variable through a series of list names, for future
> processing, I would like to print the name of the list the variable is set
> to in a given moment... i.e.
>
> for i in [alist, blist, clist]
>     i[3] = "okey dokey "
>     print(i[3], i.name)  # this is definitely not the way to do it...


One of the things you can do is make the following idea more concrete:

    You want some _name_ associated with a _value_.

In that case, you want the name 'alist' to be closely associated with
the list that goes by that name.


You can do this kind of thing without being specific to any
particularities about Python.  Directly: put that information in a
data structure, such as a dictionary.  Put the name _in_ the value.

For example:

##########################
class Person(object):
    def __init__(self, name):
        self.name = name

    def sayHi(self):
        print("this is " + self.name + "; hello!")

people = {'frank' : Person('frank'),
          'sally' : Person('sally'),
          'timothy' : Person('timothy')}

for nick, p in people.items():
    print(repr(nick) + " says: ")
    p.sayHi()
##########################


There is a reason why you might want to save the name as part of the
value, rather than to try to get that from the name of the variable.
Here's one reason: sometimes people go by different names.

##########################
tim = people['timothy']
tiny_tim = tim
tym = tim
# ... see http://en.wikipedia.org/wiki/Timothy_(name)
##########################

in which case, if we try to print out this person later on, which name
would you like to see?  Rather than guess, we might as well use the
name that timothy identifies himself with.


Good luck!

From dyoo at hashcollision.org  Fri Jan  3 07:04:53 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Thu, 2 Jan 2014 22:04:53 -0800
Subject: [Tutor] What's in a name?
In-Reply-To: <CAGZAPF4hpBfGH-yCg-+RfedPTA8OQOTK6f9SmQsawDWPs6h08A@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAGZAPF4hpBfGH-yCg-+RfedPTA8OQOTK6f9SmQsawDWPs6h08A@mail.gmail.com>
Message-ID: <CAGZAPF755oiaDry+Svep_pFkxdu+chtutaShON8TjJmY991RmQ@mail.gmail.com>

Sorry, I forgot to add.  You titled the subject of the thread as:

    "What's in a name?"


A good answer to your question is to permute the words a little.

    Name is in a... <...>


where <...> is "what" you want to put the name in.


:P

From kushal.kumaran+python at gmail.com  Fri Jan  3 07:12:09 2014
From: kushal.kumaran+python at gmail.com (Kushal Kumaran)
Date: Fri, 03 Jan 2014 11:42:09 +0530
Subject: [Tutor] sqlite3 import problem
In-Reply-To: <CACzNyA3vqHNV985m+gaePZ8Z3H-HM9cuzUMjKA_GKjGjidTwOQ@mail.gmail.com>
References: <CACzNyA3vqHNV985m+gaePZ8Z3H-HM9cuzUMjKA_GKjGjidTwOQ@mail.gmail.com>
Message-ID: <52c654c2.8707e00a.328c.ffff809b@mx.google.com>

Matthew Ngaha <chigga101 at gmail.com> writes:

> im having problems importing sqlite3 on ubuntu python3.
>
>   File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in <module>
>     from sqlite3.dbapi2 import *
>   File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in <module>
>     from _sqlite3 import *
> ImportError: No module named '_sqlite3'
>
> i have that path and file (dbapi2.py). the problem is an import
> statement for _sqlite3. i don't see this file but shouldn't python3.3
> be able to import sqlite without errors? any suggestions? does anyone
> have _sqlite3.py in their   /usr/local/lib/python3.3/sqlite3/
> directory?

The /usr/local heirarchy is not used by official debian/ubuntu packages,
so other people will not have the same contents in there as you.  You
must have a locally built python in /usr/local.  Check the build logs if
it has complained about not being able to build the sqlite3 module.  If
so, you can install all build dependencies for the offical python3
package by running this command:

# apt-get build-dep python3

And then rebuilding your local python3 installation.

-- 
regards,
kushal
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/09a2d6cb/attachment.sig>

From keithwins at gmail.com  Fri Jan  3 07:18:55 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 01:18:55 -0500
Subject: [Tutor] Fwd:  What's in a name?
In-Reply-To: <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
Message-ID: <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>

Shoot: I sent this response directly to Mark, without even trimming. Here
it is to the list...


Hi Mark: sorry for unclarity. I am probably going to make a hash of
explaining this, but here goes:

I want to iterate a variable across a list of objects, and print both the
outputs (wrong word) of said objects, and the name of the objects. Those
objects might be lists, or functions, as examples.

As a non-iterative example, something like this:

a = "max"
print(eval(a)(3,4), a)  # output: 4 max

That's the only way I can figure out how to make it work. Here's an actual
code snippet, watch for stype:

    for func in ["mean", "max", "min", "variance", "stdev"]:
            print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f}
{stype}".format(
                moves=eval(func)(tgset[1] for tgset in garray),
                chutes=eval(func)(tgset[2] for tgset in garray),
                ladders=eval(func)(tgset[3] for tgset in garray),
                stype=func
                ))

Output:
     4.67         0.21          0.79 mean
    28.00         1.00          1.00 max
     1.00         0.00          0.00 min
    23.69         0.17          0.17 variance
     4.87         0.41          0.41 stdev

I appreciate the point about eval being dangerous, though the second line
in your reference does say "if you accept strings to evaluate from
untrusted input". Still, I can appreciate how eval() could go off the
rails. Is there another way I can do what I want? Sorry for not testing the
code I posted earlier.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/f9a18544/attachment.html>

From keithwins at gmail.com  Fri Jan  3 07:28:00 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 01:28:00 -0500
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
Message-ID: <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>

Danny: I appreciate your point, but these are just for little code loops,
nothing I need to hold on to, like the snippet above: I'm just trying to
wrap a few things into one loop, which gives me flexibility about
expanding/contracting the stats, for example, that I print (by changing the
range list for "func"). Here's another code example, from my recent
masterpiece:

def print_candl_info(garray):

    game_array, chute_nums, ladder_nums = {}, chutes, ladders
    list_index = 3
    for i in chute_nums.keys(): chute_nums[i] = 0  # zero all values
    for i in ladder_nums.keys(): ladder_nums[i] = 0
    for clkeys in ["chute_nums", "ladder_nums"]:  # increment candl values
        list_index += 1  # horrible kluge: must be 4 for chutes, 5 for
ladders below
        for corl in eval(clkeys):
            for game in garray:
                if corl in game[list_index]:
                    eval(clkeys)[corl] += 1
        print("total ", clkeys, "= ", sum(list(eval(clkeys).values())))


For the purposes of answering this question, ignore the horrible kluge.
Though if you have any suggestions on that point, I'm still all ears. Since
I couldn't figure out the right way to do that, I left it as more or less
the most unforgivable kluge I could find, so I won't be able to sleep until
I improve on it. Suggestions are welcome. If it's not obvious, it relies on
the fact that the clkeys iterates precisely twice. It might be that the
answer lies in rearranging my data structure... I'm about to post the
entire program again for any comments, once I clean it up just a BIT more,
so if it's not obvious don't worry about it.

game = [int, int, int, int, [], []]  # game[4] = chutes, game[5] = ladders
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/89f8d6c4/attachment.html>

From breamoreboy at yahoo.co.uk  Fri Jan  3 07:34:51 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Fri, 03 Jan 2014 06:34:51 +0000
Subject: [Tutor] Fwd:  What's in a name?
In-Reply-To: <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
Message-ID: <la5ll3$tkt$1@ger.gmane.org>

On 03/01/2014 06:18, Keith Winston wrote:
> Shoot: I sent this response directly to Mark, without even trimming.
> Here it is to the list...
>
> Hi Mark: sorry for unclarity. I am probably going to make a hash of
> explaining this, but here goes:
>
> I want to iterate a variable across a list of objects, and print both
> the outputs (wrong word) of said objects, and the name of the objects.
> Those objects might be lists, or functions, as examples.
>
> As a non-iterative example, something like this:
>
> a = "max"
> print(eval(a)(3,4), a)  # output: 4 max
>
> That's the only way I can figure out how to make it work. Here's an
> actual code snippet, watch for stype:
>
>      for func in ["mean", "max", "min", "variance", "stdev"]:
>              print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f}
> {stype}".format(
>                  moves=eval(func)(tgset[1] for tgset in garray),
>                  chutes=eval(func)(tgset[2] for tgset in garray),
>                  ladders=eval(func)(tgset[3] for tgset in garray),
>                  stype=func
>                  ))
>

You enjoy making life difficult for yourself :)  You've assigned strings 
to the name func, just assign the functions themselves?  Like.

for func in max, min:
     print(func.__name__, func(range(5)))

Output.

max 4
min 0

> Output:
>       4.67         0.21          0.79 mean
>      28.00         1.00          1.00 max
>       1.00         0.00          0.00 min
>      23.69         0.17          0.17 variance
>       4.87         0.41          0.41 stdev
>
> I appreciate the point about eval being dangerous, though the second
> line in your reference does say "if you accept strings to evaluate from
> untrusted input". Still, I can appreciate how eval() could go off the
> rails. Is there another way I can do what I want? Sorry for not testing
> the code I posted earlier.
>

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

Mark Lawrence


From keithwins at gmail.com  Fri Jan  3 07:55:29 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 01:55:29 -0500
Subject: [Tutor] Fwd: What's in a name?
In-Reply-To: <la5ll3$tkt$1@ger.gmane.org>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <la5ll3$tkt$1@ger.gmane.org>
Message-ID: <CAO5ffbaAAc35c3ps-WmauXKhJ4HRzf87mW-hVJ1k09UT_Tfm6Q@mail.gmail.com>

Mark wrote: You enjoy making life difficult for yourself :)  You've
assigned strings to the name func, just assign the functions themselves?
 Like.

>
> for func in max, min:
>     print(func.__name__, func(range(5)))
>
> Output.
>
> max 4
> min 0
>
>
I wouldn't say I enjoy making life difficult for myself, but it is one of
my strengths ;)

That would work, I think, for the function example I gave you, but the
example I gave in response to Danny used the same trick on lists: that is,
I want to iterate through a bunch of lists, subsequently printing both list
members (via indexing, for example) and the name of the list I'm on. I
might even want to do  the same of a dict, or some random data structure.
Unless it's just really a bad idea to code like this. But certainly when
the .__name__ attribute is available, that makes more sense. I'll change
that part.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/d57e3a78/attachment-0001.html>

From breamoreboy at yahoo.co.uk  Fri Jan  3 08:23:21 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Fri, 03 Jan 2014 07:23:21 +0000
Subject: [Tutor] Fwd: What's in a name?
In-Reply-To: <CAO5ffbaAAc35c3ps-WmauXKhJ4HRzf87mW-hVJ1k09UT_Tfm6Q@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <la5ll3$tkt$1@ger.gmane.org>
 <CAO5ffbaAAc35c3ps-WmauXKhJ4HRzf87mW-hVJ1k09UT_Tfm6Q@mail.gmail.com>
Message-ID: <la5og2$nq6$1@ger.gmane.org>

On 03/01/2014 06:55, Keith Winston wrote:
> Mark wrote: You enjoy making life difficult for yourself :)  You've
> assigned strings to the name func, just assign the functions themselves?
>   Like.
>
>
>     for func in max, min:
>          print(func.__name__, func(range(5)))
>
>     Output.
>
>     max 4
>     min 0
>
>
> I wouldn't say I enjoy making life difficult for myself, but it is one
> of my strengths ;)
>
> That would work, I think, for the function example I gave you, but the
> example I gave in response to Danny used the same trick on lists: that
> is, I want to iterate through a bunch of lists, subsequently printing
> both list members (via indexing, for example) and the name of the list
> I'm on. I might even want to do  the same of a dict, or some random data
> structure. Unless it's just really a bad idea to code like this. But
> certainly when the .__name__ attribute is available, that makes more
> sense. I'll change that part.
>

lista = list(range(5))
listb = list(reversed(range(5)))
for alist in lista, listb:
     print(alist.__class__.__name__, alist)

list [0, 1, 2, 3, 4]
list [4, 3, 2, 1, 0]

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

Mark Lawrence


From keithwins at gmail.com  Fri Jan  3 08:26:40 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 02:26:40 -0500
Subject: [Tutor] Fwd: What's in a name?
In-Reply-To: <CAO5ffbaAAc35c3ps-WmauXKhJ4HRzf87mW-hVJ1k09UT_Tfm6Q@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <la5ll3$tkt$1@ger.gmane.org>
 <CAO5ffbaAAc35c3ps-WmauXKhJ4HRzf87mW-hVJ1k09UT_Tfm6Q@mail.gmail.com>
Message-ID: <CAO5ffbZUs3wNJdyi=P4-X3P6QosXgR_tvRLj0bVM609kYavQ+Q@mail.gmail.com>

I spoke about iterating through a bunch of lists in my last post, but in
fact I'm iterating through a bunch of dicts in the example I gave. Sorry.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/87ea8b93/attachment.html>

From keithwins at gmail.com  Fri Jan  3 08:34:10 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 02:34:10 -0500
Subject: [Tutor] Fwd:  Fwd: What's in a name?
In-Reply-To: <CAO5ffbYXq0V7fAdHWzVk_cH-zG-A6e70SDW+nZnAkZqrUbnCwA@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <la5ll3$tkt$1@ger.gmane.org>
 <CAO5ffbaAAc35c3ps-WmauXKhJ4HRzf87mW-hVJ1k09UT_Tfm6Q@mail.gmail.com>
 <la5og2$nq6$1@ger.gmane.org>
 <CAO5ffbYXq0V7fAdHWzVk_cH-zG-A6e70SDW+nZnAkZqrUbnCwA@mail.gmail.com>
Message-ID: <CAO5ffbZEghHGUz2tzkAp7GAtLeerRVkoFVZdx8gkpJN1vSFvCQ@mail.gmail.com>

OMG, another one to Mark and not the list. I'll see if there's something I
can adjust in email...

On Fri, Jan 3, 2014 at 2:23 AM, Mark Lawrence <breamoreboy at yahoo.co.uk>wrote:

>
> lista = list(range(5))
> listb = list(reversed(range(5)))
> for alist in lista, listb:
>     print(alist.__class__.__name__, alist)
>
> list [0, 1, 2, 3, 4]
> list [4, 3, 2, 1, 0]
>
>
> Thank you Mark for your unreasonable patience. But the output I'd like to
see from you example would be:

lista [0, 1, 2, 3, 4]
listb [4, 3, 2, 1, 0]

Which I think is not possible since the list names are lost by the time the
print statement is executing. Unless, of course, I'm wrong. I need the
instance name, I guess, not the object name, of an object that includes no
__name__ method (I'm stretching on this description)




-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/e003f8c1/attachment.html>

From dyoo at hashcollision.org  Fri Jan  3 08:42:54 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Thu, 2 Jan 2014 23:42:54 -0800
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
Message-ID: <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>

On Thu, Jan 2, 2014 at 10:28 PM, Keith Winston <keithwins at gmail.com> wrote:
> Danny: I appreciate your point, but these are just for little code loops,
> nothing I need to hold on to, like the snippet above:

I hope you don't take offense.  But I actually do not understand
print_candl_info().  I thought I did!  But then I realized I was
deluding myself.  I don't not understand it after all, and that's
after staring at it for more than about thirty minutes.

Take that a "canary in the coalmine" kind of comment.  eval() can
encourages habits that hurt program readability in a deep way.


[Note: the rest of this message is a relentless refactoring of the
original code, step by step.]



If you don't mind, I'd like to iteratively strip away the eval() and
see if we can't make it a little easier to understand.  From a first
treatment, I think this might look something like the following:

########################################################
def print_candl_info(garray):
    game_array, chute_nums, ladder_nums = {}, chutes, ladders
    for i in chute_nums.keys(): chute_nums[i] = 0
    for i in ladder_nums.keys(): ladder_nums[i] = 0

    for corl in chute_nums:
        for game in garray:
            if corl in game[4]:
                chute_nums[corl] += 1
    print("total ", "chute_nums", "= ", sum(chute_nums.values()))

    for corl in ladder_nums:
        for game in garray:
            if corl in game[5]:
                ladder_nums[corl] += 1
    print("total ", "ladder_nums", "= ", sum(ladder_nums.values()))
########################################################

where we first unroll the original's outer loop out so that there are
no eval()s anywhere.  This hurts program length a little, but we can
deal with that.  Do you agree so far that the program above preserves
the meaning of what you had before?



If we can assume that the rewritten code "means" the same thing, then
we can eliminate the duplication by doing something like this:

########################################################
def print_candl_info(garray):
    game_array, chute_nums, ladder_nums = {}, chutes, ladders
    for i in chute_nums.keys(): chute_nums[i] = 0
    for i in ladder_nums.keys(): ladder_nums[i] = 0

    summarize_game("chutes", chute_nums, 4, garray)
    summarize_game("ladders", ladder_nums, 5, garray)

def summarize_game(game_name, game_nums, game_index, garray):
    for corl in game_nums:
        for game in garray:
            if corl in game[game_index]:
                game_nums[corl] += 1
    print("total ", game_name, "= ", sum(game_nums.values()))
########################################################

where we put the the duplicated part in a function, and then call that
function twice, once for chutes, and the other for ladders.


Hmm... it's a little easier to see from this point that the "zero all
values" part also appears to be duplication.


Maybe that can be absorbed into the front of summarize_game?  Let's
iterate again.  Here's what it looks like afterwards:

########################################################
def print_candl_info(garray):
    game_array, chute_nums, ladder_nums = {}, chutes, ladders
    summarize_game("chutes", chute_nums, 4, garray)
    summarize_game("ladders", ladder_nums, 5, garray)

def summarize_game(game_name, game_nums, game_index, garray):
    for i in game_nums.keys(): game_nums[i] = 0

    for corl in game_nums:
        for game in garray:
            if corl in game[game_index]:
                game_nums[corl] += 1
    print("total ", game_name, "= ", sum(game_nums.values()))
########################################################


Reading...

Hmmm.  I don't understand why chute_nums is assigned to chutes, nor
ladder_nums to ladders, and I don't see game_array being used here
yet.  We can absorb that:


########################################################
def print_candl_info(garray):
    summarize_game("chutes", chutes, 4, garray)
    summarize_game("ladders", ladders, 5, garray)

def summarize_game(game_name, game_nums, game_index, garray):
    for i in game_nums.keys(): game_nums[i] = 0

    for corl in game_nums:
        for game in garray:
            if corl in game[game_index]:
                game_nums[corl] += 1
    print("total ", game_name, "= ", sum(game_nums.values()))
########################################################


Hmmm...  I think that's about as far as I can go with zero domain knowledge.  :P

At this point, the code makes a little more sense to me, though the
data structure still feels like a black box.  That is, I don't know
the shape of the data for 'garray' or 'corl'.  If we knew more about
the structure of the data, maybe this could be further improved.



As a side note: the code above has more latitude than the original
because it can print out a friendlier game name.  That is, for
example, you can do this:

##################################################
    summarize_game("OOOO Chutes! OOOO", chutes, 4, garray)
    summarize_game("HHHH Ladders! HHHH", ladders, 5, garray)
##################################################

From keithwins at gmail.com  Fri Jan  3 08:45:04 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 02:45:04 -0500
Subject: [Tutor] Fwd: What's in a name?
In-Reply-To: <CAO5ffbZEghHGUz2tzkAp7GAtLeerRVkoFVZdx8gkpJN1vSFvCQ@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <la5ll3$tkt$1@ger.gmane.org>
 <CAO5ffbaAAc35c3ps-WmauXKhJ4HRzf87mW-hVJ1k09UT_Tfm6Q@mail.gmail.com>
 <la5og2$nq6$1@ger.gmane.org>
 <CAO5ffbYXq0V7fAdHWzVk_cH-zG-A6e70SDW+nZnAkZqrUbnCwA@mail.gmail.com>
 <CAO5ffbZEghHGUz2tzkAp7GAtLeerRVkoFVZdx8gkpJN1vSFvCQ@mail.gmail.com>
Message-ID: <CAO5ffbaGRdaN55VydhWkcAbYW=oYCmOTCAKF_EYDMoZgJ7ciMg@mail.gmail.com>

And to beat that poor horse in the same example, my current way of doing
that would be:

for alist in "lista", "listb":
    print(alist, eval(alist))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/8db7c269/attachment.html>

From keithwins at gmail.com  Fri Jan  3 09:37:12 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 03:37:12 -0500
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
Message-ID: <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>

Below you will find the full current version of my Chutes or Snakes &
Ladders game. I tried to reorganize it into a more OOP structure, and I
think I started succeeding, and then something might have gone wrong. There
is also something somewhat seriously wrong with it: if I run it as
__main__, it works fine, but if I run it after I've loaded it (by
candl(100) at the prompt, for example), it is way off: something isn't
being reset, and I'm sure it'd be obvious to someone, and I'm going to look
back at it, but I can't figure it out yet. Anyway, thanks for all the help
so far, I'll probably add persistence, maybe trivial GUI, and definitely
more stats/analysis (well, almost definitely)...


""" Chutes & Ladders Simulation
    Simulates a number of games of Chutes & Ladders (Snakes & Ladders).
    Chutes & Ladders are separate dictionaries to allow tracking of
separate stats.

    Gathers the results into a list of lists of individual game results
    in the form (per game) of [game_no, moves, len(chutes), len(ladders),
[chutes], [ladders]]

    There is some info redundancy in the list with the len members:
[chutes] and [ladders]
    are lists of the actual chutes and ladders encountered in each game
(named by key)
"""

import random
from timer2 import timer
from statistics import * # from whence comes mean, variance, stdev


# Landing on a chute causes one to slide down to the corresponding value.
chutes = {16: 6, 47: 26, 49: 11, 56: 53, 62: 19, 64: 60, 87: 24, 93: 73,
95: 75, 98:78}

# Landing on a ladder (key) causes one to climb up to the corresponding
value.
ladders = {1: 38, 4: 14, 9: 31, 21: 42, 28: 84, 36: 44, 51: 67, 71: 91,
80:100}

class games:
    """Game class for Chutes & Ladders."""

    def __init__(self):
        self.reset()

    def reset(self):
        self.move_count = 0
        self.num_chutes = 0
        self.num_ladders = 0
        self.chutes_list = []
        self.ladders_list = []

#    @timer
    def move(self):
        """Single move, with chutes, ladders, & out of bounds.
        Primary action is to move self.position, but returns a list
        that consists of either the chute or ladder if landed on, if either
        """

        roll = random.randint(1,6)
        tchutes = 0
        tladders = 0
        self.move_count += 1
        self.position += roll
        if self.position in chutes:
            tchutes = self.position
            self.position = chutes[self.position]
            self.num_chutes += 1
        elif self.position in ladders:
            tladders = self.position
            self.position = ladders[self.position]
            self.num_ladders += 1
        elif self.position > 100:  # move doesn't count, have to land
exactly
            self.position -= roll
        return [tchutes, tladders]  # only one will be != 0

#    @timer
    def play_game(self, step):
        """Single game"""

        self.position = 0
        self.reset()
        while self.position < 100:
            gamecandl = self.move()  # [chute, ladder] or [0, 0]
            if gamecandl[0] != 0: # populate chutes list
                self.chutes_list.append(gamecandl[0])
            if gamecandl[1] != 0:  # populate ladders list
                self.ladders_list.append(gamecandl[1])
        return [step, self.move_count, self.num_chutes, self.num_ladders,
self.chutes_list, self.ladders_list]

#    @timer
    def play_gameset(self, gamecount1):
        """A set of games, returning associated stats array"""

        return [self.play_game(i) for i in range(gamecount1)]


def candl(gamecount2):
    """ play a mess of games, return the results array """

    gname = games()
    game_array = gname.play_gameset(gamecount2)
    print_gameset_stats(game_array)
    print_candl_info(game_array)
#    print(game_array)

def print_gameset_stats(garray):

    print("Total number of games: ", len(garray))
    print("   Moves        Chutes        Ladders")
    for func in [mean, max, min, variance, stdev]:
            print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f}
{stype}".format(
                moves=func(tgset[1] for tgset in garray),
                chutes=func(tgset[2] for tgset in garray),
                ladders=func(tgset[3] for tgset in garray),
                stype=func.__name__
                ))

def timing_report():

    print("game.total, count = ", p1.game.total, p1.game.count)
    print("move.total, count = ", p1.move.total, p1.move.count)

def print_candl_info(garray):
    """ Create two dictionaries with the same keys as chutes & ladders,
    but with the total number of times each c or l is traversed (in the
entire gameset)
    as the values. Then, print them. """

    chute_nums, ladder_nums = chutes, ladders
    summarize_game("chutes", chutes, 4, garray)
    summarize_game("ladders", ladders, 5, garray)

def summarize_game(game_name, game_nums, game_index, garray):
    for i in game_nums.keys(): game_nums[i] = 0

    for corl in game_nums:
        for game in garray:
            if corl in game[game_index]:
                game_nums[corl] += 1
    print("total ", game_name, "= ", sum(game_nums.values()))


if __name__ == "__main__":
    candl(100)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/5321a602/attachment-0001.html>

From pasokan at talentsprint.com  Fri Jan  3 10:27:01 2014
From: pasokan at talentsprint.com (Asokan Pichai)
Date: Fri, 3 Jan 2014 14:57:01 +0530
Subject: [Tutor] Fwd: What's in a name?
In-Reply-To: <CAO5ffbaGRdaN55VydhWkcAbYW=oYCmOTCAKF_EYDMoZgJ7ciMg@mail.gmail.com>
References: <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <la5ll3$tkt$1@ger.gmane.org>
 <CAO5ffbaAAc35c3ps-WmauXKhJ4HRzf87mW-hVJ1k09UT_Tfm6Q@mail.gmail.com>
 <la5og2$nq6$1@ger.gmane.org>
 <CAO5ffbYXq0V7fAdHWzVk_cH-zG-A6e70SDW+nZnAkZqrUbnCwA@mail.gmail.com>
 <CAO5ffbZEghHGUz2tzkAp7GAtLeerRVkoFVZdx8gkpJN1vSFvCQ@mail.gmail.com>
 <CAO5ffbaGRdaN55VydhWkcAbYW=oYCmOTCAKF_EYDMoZgJ7ciMg@mail.gmail.com>
Message-ID: <20140103092701.GB4518@shifu.pasokan.in>

On Fri, Jan 03, 2014 at 02:45:04AM -0500, Keith Winston wrote:
> And to beat that poor horse in the same example, my current way of doing
> that would be:
> 
> for alist in "lista", "listb":
>     print(alist, eval(alist))

Since you know both pieces, namely the name of the entity "alist" and its 
actual symbol aka alist, why not do something like:

    Lists = {"lista": lista, "listb": lisb}

and use
    Lists[x] ...

HTH

Asokan Pichai


From keithwins at gmail.com  Fri Jan  3 09:26:58 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 03:26:58 -0500
Subject: [Tutor] What's in a name?
In-Reply-To: <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
Message-ID: <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>

On Fri, Jan 3, 2014 at 2:42 AM, Danny Yoo <dyoo at hashcollision.org> wrote:

>
> I hope you don't take offense.  But I actually do not understand
> print_candl_info().  I thought I did!  But then I realized I was
> deluding myself.  I don't not understand it after all, and that's
> after staring at it for more than about thirty minutes.
>
>
I dare you to try to offend me, while offering helpful comments! Okay, I
take that back. Anyway, no I don't.


> Take that a "canary in the coalmine" kind of comment.  eval() can
> encourages habits that hurt program readability in a deep way.
>
> Fair enough.


> where we first unroll the original's outer loop out so that there are
> no eval()s anywhere.  This hurts program length a little, but we can
> deal with that.  Do you agree so far that the program above preserves
> the meaning of what you had before?
>
>
Ha ha, you must understand, because you recreated the original form of the
code. First, realize that this is all a learning exercise for me, I am not
actually obsessed by Chutes & Ladders. So I was trying to figure out if I
could do this thing of iterating over a list of (functions, lists,
dictionaries) and print both some output related to the object, and the
objects name. But I think you now understand that. In this _particular_
case, I've got that little list_index kluge, which is probably good, since
it sort of forces me to try to solve a more general case (or get other
people to!... er, thanks!)


>
> If we can assume that the rewritten code "means" the same thing, then
> we can eliminate the duplication by doing something like this:
>
> ########################################################
> def print_candl_info(garray):
>     game_array, chute_nums, ladder_nums = {}, chutes, ladders
>     for i in chute_nums.keys(): chute_nums[i] = 0
>     for i in ladder_nums.keys(): ladder_nums[i] = 0
>
>     summarize_game("chutes", chute_nums, 4, garray)
>     summarize_game("ladders", ladder_nums, 5, garray)
>
>
I see what you did there.


> Hmmm.  I don't understand why chute_nums is assigned to chutes, nor
> ladder_nums to ladders, and I don't see game_array being used here
> yet.  We can absorb that:
>
>
>
Yes, game_array was left over, sorry. But chutes and ladders are
dictionaries that should remain unchanged, for the purpose of future games.
chute_nums = chutes only b/c that was an easy way to fill in all the keys:
I then zero out the values, and increment the values for every time any
given chute or ladder is traversed during a game (this information is in
game[4] and game[5], each of which are lists of the chutes or ladders
traversed in each given game). I hope that's clear. So I think you can't
lose that, or you'd have to fill in those keys differently (which is how I
did it at first, but this approach seemed cleaner).

########################################################
> def print_candl_info(garray):
>     summarize_game("chutes", chutes, 4, garray)
>     summarize_game("ladders", ladders, 5, garray)
>
> def summarize_game(game_name, game_nums, game_index, garray):
>     for i in game_nums.keys(): game_nums[i] = 0
>
>     for corl in game_nums:
>         for game in garray:
>             if corl in game[game_index]:
>                 game_nums[corl] += 1
>     print("total ", game_name, "= ", sum(game_nums.values()))
> ########################################################
>
>
This is definitely an improvement, IMO. Summarize_game is _almost_ a really
good name, but it isn't really summarizing a single game: it's iterating
over all the games in garray (the array of games), and adding up all the
particular chutes and ladders occurrences, if I haven't already made that
clear... It's sneaky like that. I'm tempted to say summarize_candl, but
candl is getting boring... I'll leave it for now.



> As a side note: the code above has more latitude than the original
> because it can print out a friendlier game name.  That is, for
> example, you can do this:
>
> ##################################################
>     summarize_game("OOOO Chutes! OOOO", chutes, 4, garray)
>     summarize_game("HHHH Ladders! HHHH", ladders, 5, garray)
> ##################################################
>


Yep, true that.

Thanks Danny, this was instructive. Very kind of you.
-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/3b0b9b44/attachment.html>

From dyoo at hashcollision.org  Fri Jan  3 10:34:26 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 3 Jan 2014 01:34:26 -0800
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
Message-ID: <CAGZAPF4WG2pKvkQuHCzgokWvQO5JFaf3x53GEmEwsB-vkPqLFQ@mail.gmail.com>

> it works fine, but if I run it after I've loaded it (by candl(100) at the
> prompt, for example), it is way off: something isn't being reset, and I'm
> sure it'd be obvious to someone,

It's due to global variable mutation.  Note that summarize_game()
mutates game_nums, which is either chutes or ladders.  Basically, it
writes all over the structure of the game board, which means
subsequent play throughs are a wash.  :P

And you know this, from your comment:

> Yes, game_array was left over, sorry. But chutes and ladders are
> dictionaries that should remain unchanged, for the purpose of
> future games.

But to be fair, this problem was also present in the original version
of the code, before my meddling.


This is relatively straightforward to fix: just modify summarize_game
so it creates a fresh dictionary mimicking the key structure of the
entry points.  That way, it doesn't mess with chutes and ladders.

##########################################################
def summarize_game(game_name, game_map, game_index, garray):
    game_nums = {}
    for i in game_map.keys(): game_nums[i] = 0
    for corl in game_nums:
        for game in garray:
            if corl in game[game_index]:
                game_nums[corl] += 1
    print("total ", game_name, "= ", sum(game_nums.values()))
##########################################################


In the context of the full program, I now understand why you have "4"
and "5" as mysterious constants now.  Good.  It's due to the structure
of the return value of games.play_game().

#################################################
return [step, self.move_count, self.num_chutes, self.num_ladders,
self.chutes_list, self.ladders_list]
#################################################

That is, this awkwardness of indexing by number to get at chutes_list
and ladders_list is due to that result wanting not to be in a
homogenous list or sequence.  The return value there *really* wants to
be something more like a dictionary or object instead.


Don't have time at the moment to sketch more than that; must sleep so
I can work tomorrow.  :P

From dyoo at hashcollision.org  Fri Jan  3 10:50:45 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 3 Jan 2014 01:50:45 -0800
Subject: [Tutor] What's in a name?
In-Reply-To: <CAGZAPF4WG2pKvkQuHCzgokWvQO5JFaf3x53GEmEwsB-vkPqLFQ@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <CAGZAPF4WG2pKvkQuHCzgokWvQO5JFaf3x53GEmEwsB-vkPqLFQ@mail.gmail.com>
Message-ID: <CAGZAPF7KFKDGCTempB+Q74E9g=TLt2FS7ADwtBWuOS36BDW_0w@mail.gmail.com>

Quick thing.  Please look at the following small program:

#################
d1 = {1 : 'one'}
d2 = d1
d2[2] = 'two'
print(d1)
print(d2)
#################

Predict what this prints out.  Write your prediction on a piece of paper.

Then run the program.  Does it match what you wrote?

If not, start asking questions.  If so, then I'm puzzled.  :P



The reason I ask is because of the comment:

> But chutes and ladders are dictionaries that should remain
> unchanged, for the purpose of future games.

which has several meanings that I did not anticipate.  So I need to
make sure you're ok on all those things.  :P

From christian.h.alexander at gmail.com  Fri Jan  3 09:30:17 2014
From: christian.h.alexander at gmail.com (Christian Alexander)
Date: Fri, 3 Jan 2014 03:30:17 -0500
Subject: [Tutor] Mastering the fundamentals
Message-ID: <CABSj3_45VsV0bh_71+d+f4Sn+Ta-=bOO6M5NYDtkZ6cmAyB+Xw@mail.gmail.com>

Hello Tutorians,

I've just recently acquired "Learning Python", and I must state that it is
a fairly thorough book.  However it seems as if I am learning at a very
slow pace, so my question is, as far as setting a goal to master the
basics, where should I be within a years time?  Assuming I spend at least 2
hours of actual coding time per day.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/1f19d878/attachment.html>

From alan.gauld at btinternet.com  Fri Jan  3 11:36:40 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 03 Jan 2014 10:36:40 +0000
Subject: [Tutor] sqlite3 import problem
In-Reply-To: <CACzNyA3vqHNV985m+gaePZ8Z3H-HM9cuzUMjKA_GKjGjidTwOQ@mail.gmail.com>
References: <CACzNyA3vqHNV985m+gaePZ8Z3H-HM9cuzUMjKA_GKjGjidTwOQ@mail.gmail.com>
Message-ID: <la63rc$faa$1@ger.gmane.org>

On 03/01/14 02:17, Matthew Ngaha wrote:
> im having problems importing sqlite3 on ubuntu python3.
>
>    File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in <module>
>      from sqlite3.dbapi2 import *
>    File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in <module>
>      from _sqlite3 import *
> ImportError: No module named '_sqlite3'

As a matter of interest why do you have the underscore in front of 
sqlite3? Is that deliberate?

I normally import it with just

import sqlite3
or
from sqlite3 import ...



-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Fri Jan  3 12:41:06 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 03 Jan 2014 11:41:06 +0000
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
Message-ID: <la67k7$olk$1@ger.gmane.org>

On 03/01/14 08:37, Keith Winston wrote:
> Below you will find the full current version of my Chutes or Snakes &
> Ladders game. I tried to reorganize it into a more OOP structure,

This is off topic but a couple of points about the OOP stuff...

Its normal style to name classes with a capital letter so it
would be Games not games.

It's also better to name classes as a singular. They create
a single object not many so it would really be Game not Games.

Finally the class name should be specific to what the class
is. You class is not a generic game class its very specifically
a ChutesAndLadders game class.

So a better name is

class ChutesAndLadders:...

Finally, one comment that is more apropos to the current thread.
You started by saying:

"If I'm iterating a variable through a series of list names,
for future processing, I would like to print the name of the
list the variable is set to in a given moment... "

Remember that variables in Python are just names.
So we can rewrite your statement as

"If I'm iterating a name through a series of list names, for future 
processing, I would like to print the name of the list the name is set 
to in a given moment... "

And since the list names are just strings we can write:

"If I'm iterating a name through a list of strings, for future 
processing, I would like to print the name in a given moment...

So the answer to your question is just to print the string.
The real challenge, as we have discovered, is how to access
the list that is named by the string. And the usual way to
map strings to objects is via a dictionary not by using eval().

Which kind of takes us back to where we were...


> class games:
>      """Game class for Chutes & Ladders."""
>
>      def __init__(self):
>          self.reset()
>
>      def reset(self):
>          self.move_count = 0
>          self.num_chutes = 0
>          self.num_ladders = 0
>          self.chutes_list = []
>          self.ladders_list = []

Do you really need the num_xxx variables?
Using len(xxx_list) is more reliable that depending on your
code to maintain the values. It may be that you need them
for a performance optimisation but given that games are
not normally CPU bound that seems unlikely.

Or does num_xxx indicate something different?
Looking briefly at the move()  code it may be they
represent the number of xxx encountered during the game?

>      def move(self):
>          """Single move, with chutes, ladders, & out of bounds.
>          Primary action is to move self.position, but returns a list
>          that consists of either the chute or ladder if landed on, if either
>          """
>
>          roll = random.randint(1,6)
>          tchutes = 0
>          tladders = 0
>          self.move_count += 1
>          self.position += roll
>          if self.position in chutes:
>              tchutes = self.position
>              self.position = chutes[self.position]
>              self.num_chutes += 1
>          elif self.position in ladders:
>              tladders = self.position
>              self.position = ladders[self.position]
>              self.num_ladders += 1
>          elif self.position > 100:  # move doesn't count, have to land
> exactly
>              self.position -= roll
>          return [tchutes, tladders]  # only one will be != 0

I don't understand the tchutes/tladders stuff? They hold the
target position or zero (the return comment is wrong BTW since both
could be zero). Why not just have a single variable called target
or somesuch? Also if you must return two values its probably better to 
use a tuple rather than a list.

>      def play_game(self, step):
>          """Single game"""

Since this is part of a games/Game/ChutesAndLadders class you probably 
don't need the '_game' bit of the name, it doesn't convey any extra 
information. Just a thought...

>          self.position = 0
>          self.reset()

Shouldn't the self.position assignment be part of reset()?

>          while self.position < 100:
>              gamecandl = self.move()  # [chute, ladder] or [0, 0]
>              if gamecandl[0] != 0: # populate chutes list
>                  self.chutes_list.append(gamecandl[0])
>              if gamecandl[1] != 0:  # populate ladders list
>                  self.ladders_list.append(gamecandl[1])

Why don't you do this update of the lists in the move() code.
It's where it logically happens and saves passing back the
list/tuple and then having to test it here.  This just adds
extra work.

>          return [step, self.move_count, self.num_chutes,
> self.num_ladders, self.chutes_list, self.ladders_list]

In OOP you rarely have to return attributes. And since step
is passed in as an argument the caller already knows. So I
don't think you really need to return anything here.

> #    @timer
>      def play_gameset(self, gamecount1):
>          """A set of games, returning associated stats array"""
>
>          return [self.play_game(i) for i in range(gamecount1)]

OK, I see now, you are storing the current state values
after each game. Personally I'd probably create another
method called (get_stats() or similar and have play() return 
success/failure.

Then your line above would be:

return [self.get_stats() for i in range(gamecount) if self.play()]

It keeps the purpose of the methods explicit. play() plays the game, 
get_stats() returns the data.

But there is another more OOP approach.
Create a game instance for each iteration.
Then collect the instances which then hold the data.
No need for all the extra arrays, return values, etc.
It's by using and passing whole *objects* around that
it is *Object Oriented*. We are trying to move away
from knowing about the internal data.

> def candl(gamecount2):
>      """ play a mess of games, return the results array """
>
>      gname = games()

So rather than having a game instance created here create
it in play_gameset which becomes a function  rather than
a method... And if play() returns self...

def play_gameset(count):
     return [ChutesAndLadders().play() for n in range(count)]

If you wanted to create other games later you could even
extend it to take the game class as an argument:

def play_gameset(count, game):
     return [game().play() for n in range(count)]

>      game_array = gname.play_gameset(gamecount2)

game_array then truly is an array of game objects.

>      print_gameset_stats(game_array)
>      print_candl_info(game_array)

And the stats functions calculate their stats by extracting
them from the objects (using our get_stats() method of course! :-)

In general if you create a class then only have a single instance
that's a bad OOP sign. You probably only need a module... (There are 
situations where a singleton object is useful, but in Python its very rare)

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Fri Jan  3 12:47:58 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 03 Jan 2014 11:47:58 +0000
Subject: [Tutor] Mastering the fundamentals
In-Reply-To: <CABSj3_45VsV0bh_71+d+f4Sn+Ta-=bOO6M5NYDtkZ6cmAyB+Xw@mail.gmail.com>
References: <CABSj3_45VsV0bh_71+d+f4Sn+Ta-=bOO6M5NYDtkZ6cmAyB+Xw@mail.gmail.com>
Message-ID: <la6813$t8n$1@ger.gmane.org>

On 03/01/14 08:30, Christian Alexander wrote:

> I've just recently acquired "Learning Python", and I must state that it
> is a fairly thorough book.  However it seems as if I am learning at a
> very slow pace, so my question is, as far as setting a goal to master
> the basics, where should I be within a years time?

It depends on where you start from. Can you program in other languages?
If so you should be very comfortable with Python programming in a year
(probably much less).

If you have never programmed before then Learning Python may not be the 
best tutorial since it assumes quite a lot of programming jargon etc is 
understood but if you persevere you should know the language well enough 
to write moderate sized programs (a few hundred lines say).

Is that meaningful? Maybe not.
To try a musical analogy, after a year you should be able to play 
simplified versions of popular tunes well enough that your friends 
recognize them and sing along. You could probably even try busking
in the street for pennies. But you probably aren't going to be getting 
signed by Simon Cowell anytime soon.

hth
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From chigga101 at gmail.com  Fri Jan  3 14:17:31 2014
From: chigga101 at gmail.com (Matthew Ngaha)
Date: Fri, 3 Jan 2014 13:17:31 +0000
Subject: [Tutor] sqlite3 import problem
In-Reply-To: <la63rc$faa$1@ger.gmane.org>
References: <CACzNyA3vqHNV985m+gaePZ8Z3H-HM9cuzUMjKA_GKjGjidTwOQ@mail.gmail.com>
 <la63rc$faa$1@ger.gmane.org>
Message-ID: <CACzNyA23JqKyVroEOrMqpPhxGdxVB1cqG31QL6+LA9TWX47Zgw@mail.gmail.com>

On Fri, Jan 3, 2014 at 10:36 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 03/01/14 02:17, Matthew Ngaha wrote:
>>
>> im having problems importing sqlite3 on ubuntu python3.
>>
>>    File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in
>> <module>
>>      from sqlite3.dbapi2 import *
>>    File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in <module>
>>      from _sqlite3 import *
>> ImportError: No module named '_sqlite3'
>
>
> As a matter of interest why do you have the underscore in front of sqlite3?
> Is that deliberate?
>
> I normally import it with just
>
> import sqlite3
> or
> from sqlite3 import ...

Hi Alan. The code in the traceback is being done internally. my code
has "import sqlite3". Python finds it in this directory:

/usr/local/lib/python3.3/sqlite3/

and runs the code from the traceback. I have no idea why it's using _sqlite3:(

On Fri, Jan 3, 2014 at 6:12 AM, Kushal Kumaran
<kushal.kumaran+python at gmail.com> wrote:
> The /usr/local heirarchy is not used by official debian/ubuntu packages,
> so other people will not have the same contents in there as you.  You
> must have a locally built python in /usr/local.  Check the build logs if
> it has complained about not being able to build the sqlite3 module.  If
> so, you can install all build dependencies for the offical python3
> package by running this command:
>
> # apt-get build-dep python3
>
> And then rebuilding your local python3 installation.
>

On Fri, Jan 3, 2014 at 3:00 AM, Danny Yoo <dyoo at hashcollision.org> wrote:
> This might be an Ubuntu bug or deficiency.

Hi, Danny & Kushal.
Originally i only had python 2.7 and 3.2 as default for Ubuntu. Kushal
you're right my 3.2 has a different path to sqlite3 than

/usr/local/lib/python3.3/sqlite3/

Infact i haven't been able to find its location. 3.2 imports sqlite3
with no errors. I'm currently not on ubuntu to try your instruction.
Will the build logs be inside the python3.3 directory? I'm still new
to linux so sorry for newbie questions. it took me a very long time to
get it right when building python3.3. When you say rebuild, is there a
command for doing that or do you mean simply uninstall python then
build it again?

On Fri, Jan 3, 2014 at 10:36 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 03/01/14 02:17, Matthew Ngaha wrote:
>>
>> im having problems importing sqlite3 on ubuntu python3.
>>
>>    File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in
>> <module>
>>      from sqlite3.dbapi2 import *
>>    File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in <module>
>>      from _sqlite3 import *
>> ImportError: No module named '_sqlite3'
>
>
> As a matter of interest why do you have the underscore in front of sqlite3?
> Is that deliberate?
>
> I normally import it with just
>
> import sqlite3
> or
> from sqlite3 import ...
>
>
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> 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 breamoreboy at yahoo.co.uk  Fri Jan  3 14:36:05 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Fri, 03 Jan 2014 13:36:05 +0000
Subject: [Tutor] sqlite3 import problem
In-Reply-To: <la63rc$faa$1@ger.gmane.org>
References: <CACzNyA3vqHNV985m+gaePZ8Z3H-HM9cuzUMjKA_GKjGjidTwOQ@mail.gmail.com>
 <la63rc$faa$1@ger.gmane.org>
Message-ID: <la6ebp$2u2$1@ger.gmane.org>

On 03/01/2014 10:36, Alan Gauld wrote:
> On 03/01/14 02:17, Matthew Ngaha wrote:
>> im having problems importing sqlite3 on ubuntu python3.
>>
>>    File "/usr/local/lib/python3.3/sqlite3/__init__.py", line 23, in
>> <module>
>>      from sqlite3.dbapi2 import *
>>    File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in
>> <module>
>>      from _sqlite3 import *
>> ImportError: No module named '_sqlite3'
>
> As a matter of interest why do you have the underscore in front of
> sqlite3? Is that deliberate?
>
> I normally import it with just
>
> import sqlite3
> or
> from sqlite3 import ...
>

You surprise me Alan, this is an oft used idiom in Python.  A typical 
example would be having a fast C module but if this can't be imported 
fall back to a Python implementation.

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

Mark Lawrence


From sahaf525 at gmail.com  Fri Jan  3 12:24:56 2014
From: sahaf525 at gmail.com (Al-Sahaf, Ahmed H.)
Date: Fri, 3 Jan 2014 14:24:56 +0300
Subject: [Tutor] Mastering the fundamentals
In-Reply-To: <CABSj3_45VsV0bh_71+d+f4Sn+Ta-=bOO6M5NYDtkZ6cmAyB+Xw@mail.gmail.com>
References: <CABSj3_45VsV0bh_71+d+f4Sn+Ta-=bOO6M5NYDtkZ6cmAyB+Xw@mail.gmail.com>
Message-ID: <CANhjKsHTWW-W4+G=jYAvv9fY8DGBvp-W=0WBg9kx27zDZ1UABA@mail.gmail.com>

Hi Christian,

You can start with Google Python Class

https://developers.google.com/edu/python/

Best regards,
Ahmed
On Jan 3, 2014 1:29 PM, "Christian Alexander" <
christian.h.alexander at gmail.com> wrote:

> Hello Tutorians,
>
> I've just recently acquired "Learning Python", and I must state that it is
> a fairly thorough book.  However it seems as if I am learning at a very
> slow pace, so my question is, as far as setting a goal to master the
> basics, where should I be within a years time?  Assuming I spend at least 2
> hours of actual coding time per day.
>
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/e0eea9f0/attachment-0001.html>

From alan.gauld at btinternet.com  Fri Jan  3 14:44:11 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 03 Jan 2014 13:44:11 +0000
Subject: [Tutor] sqlite3 import problem
In-Reply-To: <la6ebp$2u2$1@ger.gmane.org>
References: <CACzNyA3vqHNV985m+gaePZ8Z3H-HM9cuzUMjKA_GKjGjidTwOQ@mail.gmail.com>
 <la63rc$faa$1@ger.gmane.org> <la6ebp$2u2$1@ger.gmane.org>
Message-ID: <la6eqv$73g$1@ger.gmane.org>

On 03/01/14 13:36, Mark Lawrence wrote:

>>>    File "/usr/local/lib/python3.3/sqlite3/dbapi2.py", line 26, in
>>> <module>
>>>      from _sqlite3 import *
>>> ImportError: No module named '_sqlite3'
>>
>> As a matter of interest why do you have the underscore in front of
>> sqlite3? Is that deliberate?
>
> You surprise me Alan, this is an oft used idiom in Python.  A typical
> example would be having a fast C module but if this can't be imported
> fall back to a Python implementation.

Yes, but that's usually hidden from the user...
I didn't look closely enough at the file names in the traceback
and assumed the OP was explicitly importing using the underscore.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From denis.spir at gmail.com  Fri Jan  3 15:03:06 2014
From: denis.spir at gmail.com (spir)
Date: Fri, 03 Jan 2014 15:03:06 +0100
Subject: [Tutor] What's in a name?
In-Reply-To: <la67k7$olk$1@ger.gmane.org>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <la67k7$olk$1@ger.gmane.org>
Message-ID: <52C6C31A.80608@gmail.com>

On 01/03/2014 12:41 PM, Alan Gauld wrote:
>
>>          return [step, self.move_count, self.num_chutes,
>> self.num_ladders, self.chutes_list, self.ladders_list]
>
> In OOP you rarely have to return attributes. And since step
> is passed in as an argument the caller already knows [it]. So I
> don't think you really need to return anything here.

Maybe the intent here (except from the case of step) is to conceptually isolate 
another part of code from the current object (here a 'game'), or from this 
method (play_game). So that don't they interact in a hidden way (that one cannot 
guess from the outside, without reading code in detail). In other words, to make 
code _transparent_, which is indeed a common advice (and one I approve).

In this, to have the caller explicitely, obviously read information about the 
'game' object, one could just:
	return self

However, this makes no sense if the caller the cirrent method, play_game, is 
another method of the 'game' ;-). In this case, indeed return nothing.

(All this, if I correctly understand and interpret.)

Denis

From denis.spir at gmail.com  Fri Jan  3 15:09:17 2014
From: denis.spir at gmail.com (spir)
Date: Fri, 03 Jan 2014 15:09:17 +0100
Subject: [Tutor] Mastering the fundamentals
In-Reply-To: <CABSj3_45VsV0bh_71+d+f4Sn+Ta-=bOO6M5NYDtkZ6cmAyB+Xw@mail.gmail.com>
References: <CABSj3_45VsV0bh_71+d+f4Sn+Ta-=bOO6M5NYDtkZ6cmAyB+Xw@mail.gmail.com>
Message-ID: <52C6C48D.40709@gmail.com>

On 01/03/2014 09:30 AM, Christian Alexander wrote:
> Hello Tutorians,
>
> I've just recently acquired "Learning Python", and I must state that it is
> a fairly thorough book.  However it seems as if I am learning at a very
> slow pace, so my question is, as far as setting a goal to master the
> basics, where should I be within a years time?  Assuming I spend at least 2
> hours of actual coding time per day.

I'd say there is no common pace. Differences between (future) programmers are 
huge. Also faster pace at a given period does not mean higher quality or 
competence eventually, and lower pace at a given period does not mean lower 
quality or competence eventually.

(This applies to any complex or creative domain.)

(I'd also say: do as you feel it; listen to, be confident in, follow your 
intuition; who alse can know what's good [pace] for you.)

Denis


From emile at fenx.com  Fri Jan  3 17:53:41 2014
From: emile at fenx.com (emile)
Date: Fri, 03 Jan 2014 08:53:41 -0800
Subject: [Tutor] ValueError: could not convert string to float: '13,2'
In-Reply-To: <l9vb2h$rqn$1@ger.gmane.org>
References: <52C2CC62.60300@ncf.ca> <l9vb2h$rqn$1@ger.gmane.org>
Message-ID: <la6pub$ebs$1@ger.gmane.org>

On 12/31/2013 12:56 PM, Mark Lawrence wrote:
> import locale
>
> # Set to users preferred locale:
> locale.setlocale(locale.LC_ALL, '')
> # Or a specific locale:
> locale.setlocale(locale.LC_NUMERIC, "en_DK.UTF-8")
> print(locale.atof("3,14"))


This is a good solution, but be aware that it could impact other parts 
of your porgram as well, particularly if this is a read in data set from 
a non-local region.  Also, in places where commas are used as decimal 
points, it's also common to use periods as commas:

 >>> print(locale.atof("123.456,14"))
123456.14

Emile






From eryksun at gmail.com  Fri Jan  3 18:49:48 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 3 Jan 2014 12:49:48 -0500
Subject: [Tutor] ValueError: could not convert string to float: '13,2'
In-Reply-To: <la6pub$ebs$1@ger.gmane.org>
References: <52C2CC62.60300@ncf.ca> <l9vb2h$rqn$1@ger.gmane.org>
 <la6pub$ebs$1@ger.gmane.org>
Message-ID: <CACL+1asaS1SxWpna5CVVp1M3wDZU=RFbdYFEOVNViZj2nv+egg@mail.gmail.com>

On Fri, Jan 3, 2014 at 11:53 AM, emile <emile at fenx.com> wrote:
> On 12/31/2013 12:56 PM, Mark Lawrence wrote:
>>
>> import locale
>>
>> # Set to users preferred locale:
>> locale.setlocale(locale.LC_ALL, '')
>> # Or a specific locale:
>> locale.setlocale(locale.LC_NUMERIC, "en_DK.UTF-8")
>> print(locale.atof("3,14"))
>
> This is a good solution, but be aware that it could impact other parts of
> your porgram as well, particularly if this is a read in data set from a
> non-local region.  Also, in places where commas are used as decimal points,
> it's also common to use periods as commas:
>
>>>> print(locale.atof("123.456,14"))
> 123456.14

If you're writing a library, don't modify the process locale. That's
for an application to set, preferably only once at startup. Use some
other library such as ICU:

    >>> import icu

    >>> lc = icu.Locale.createCanonical('da_DK.utf-8')
    >>> lc.getDisplayLanguage()
    'Danish'
    >>> lc.getDisplayCountry()
    'Denmark'

    >>> nf = icu.NumberFormat.createInstance(lc)
    >>> nf.parse('123.456,14').getDouble()
    123456.14

http://userguide.icu-project.org/locale
http://userguide.icu-project.org/formatparse/numbers

From keithwins at gmail.com  Fri Jan  3 19:53:42 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 13:53:42 -0500
Subject: [Tutor] What's in a name?
In-Reply-To: <CAGZAPF7KFKDGCTempB+Q74E9g=TLt2FS7ADwtBWuOS36BDW_0w@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <CAGZAPF4WG2pKvkQuHCzgokWvQO5JFaf3x53GEmEwsB-vkPqLFQ@mail.gmail.com>
 <CAGZAPF7KFKDGCTempB+Q74E9g=TLt2FS7ADwtBWuOS36BDW_0w@mail.gmail.com>
Message-ID: <CAO5ffbZY4JbzS0ygbOtUm8MsmCWeRW_z-NOoxQ=Q6eCAGr0hzQ@mail.gmail.com>

On Fri, Jan 3, 2014 at 4:50 AM, Danny Yoo <dyoo at hashcollision.org> wrote:

> Quick thing.  Please look at the following small program:
>
> #################
> d1 = {1 : 'one'}
> d2 = d1
> d2[2] = 'two'
> print(d1)
> print(d2)
> #################
>
> Predict what this prints out.  Write your prediction on a piece of paper.
>
> Then run the program.  Does it match what you wrote?
>
> If not, start asking questions.  If so, then I'm puzzled.  :P
>
>
> Thanks Danny: I understand this issue when I'm looking right at it, but it
can still slip past me with a moments inattention... as soon as you pointed
it out, I bruised my forehead by slapping it so hard. Thanks.

Actually, it's funnier than that: I now notice that the code I swiped from
you passes the original arrays, not even the "copies" which aren't copies.
That's what I meant to do: make a copy when I wrote chute_nums = chutes. So
I should have passed chute_nums to summarize_game, but it still wouldn't
work (because it's not a copy). More below.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/580dc927/attachment.html>

From keithwins at gmail.com  Fri Jan  3 20:25:37 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 14:25:37 -0500
Subject: [Tutor] What's in a name?
In-Reply-To: <52C6C31A.80608@gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <la67k7$olk$1@ger.gmane.org> <52C6C31A.80608@gmail.com>
Message-ID: <CAO5ffbY70jtcQ_3ao-LHKPFC6LXWjN=RJLcWw-UhGV9KQL-TNw@mail.gmail.com>

On Fri, Jan 3, 2014 at 9:03 AM, spir <denis.spir at gmail.com> wrote:

> On 01/03/2014 12:41 PM, Alan Gauld wrote:
>
>>
>>           return [step, self.move_count, self.num_chutes,
>>> self.num_ladders, self.chutes_list, self.ladders_list]
>>>
>>
>> In OOP you rarely have to return attributes. And since step
>> is passed in as an argument the caller already knows [it]. So I
>>
>> don't think you really need to return anything here.
>>
>
Alas, it's uglier than all that, and probably inherently non-OOP organized.
The calling method DOES know the step variable (attribute? it's not part of
a class, is it still an attribute?), since it's using it to iterate through
a list: but that variable is gone by the time the play_game returns, and
yet I want to ensconce it in the data structure to keep track of the
different games... And so I pass it in to save it to the data structure.
It's ugly, and probably not the right way to do that (post script: I think
I figured this out below).

Calling method:
        return [self.play_game(i) for i in range(gamecount1)]

   def play_game(self, step):
        # various stuff happens, but step is just passed through to be
stored in the structure that the calling method is contributing to
        return [step, self.move_count, self.num_chutes, self.num_ladders,
self.chutes_list, self.ladders_list]



> Maybe the intent here (except from the case of step) is to conceptually
> isolate another part of code from the current object (here a 'game'), or
> from this method (play_game). So that don't they interact in a hidden way
> (that one cannot guess from the outside, without reading code in detail).
> In other words, to make code _transparent_, which is indeed a common advice
> (and one I approve).
>
> In this, to have the caller explicitely, obviously read information about
> the 'game' object, one could just:
>         return self
>
> However, this makes no sense if the caller the cirrent method, play_game,
> is another method of the 'game' ;-). In this case, indeed return nothing.
>
> (All this, if I correctly understand and interpret.)
>
> Denis


Well, I sort of mangle OOP still. Here's the issue: I have this play_game
method of Game, which returns/fills in the "results" of a game in the form
of a list of ints & lists. What I though I want is to play lots of games,
gather all those game "results" into a big array (just another list really,
of course), and then do stats/analsis on that array. But I think my
thinking is broken here: I am trying to create a list of game results,
whereas I should be creating a list of games (with their corresponding
attributes)... And that should happen altogether outside the Game glass. I
imagine I should have another class for that, say GameArray... but that's
just a first thought on the next reorganization...

So I guess my Game class should have an attribute like game_number,
corresponding to step variable above, and GameArray should do something
like...

game1 = Game() # instance of Game
for i in range(gamecount): game_array[i] = game1.play_game(i)

(inside play_game: self.game_number = i)

And I guess GameArray can hold all the stats/analysis/printing functions,
since that's the object they operate on...

This sounds like the right direction here, but I don't completely trust my
own thinking yet on this stuff. In retrospect, my need for a reset method
probably indicated I was going the wrong direction, and probably popped up
as soon as I tried to deal with a multitude of games within the Game class
itself.

thanks as always!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/3453d3bd/attachment-0001.html>

From iafleischer at gmail.com  Fri Jan  3 20:35:47 2014
From: iafleischer at gmail.com (I. Alejandro Fleischer)
Date: Fri, 3 Jan 2014 16:35:47 -0300
Subject: [Tutor] idle problem
Message-ID: <CAHNAVNt_K44pShKFwjKubk2t-Lq3NTzSb6YB55Fp_6OTwUePPw@mail.gmail.com>

Hello to everyone,

Sudenly Im having troubles opening files with the idle editor. When I open
a file it appears in blank, and can not close it anymore.

My OS is ubuntu 13.10 (64 bits) and my python version is 2.7.5.

Regards,

Igor
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/fcbbd9ca/attachment.html>

From eryksun at gmail.com  Fri Jan  3 20:58:31 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 3 Jan 2014 14:58:31 -0500
Subject: [Tutor] idle problem
In-Reply-To: <CAHNAVNt_K44pShKFwjKubk2t-Lq3NTzSb6YB55Fp_6OTwUePPw@mail.gmail.com>
References: <CAHNAVNt_K44pShKFwjKubk2t-Lq3NTzSb6YB55Fp_6OTwUePPw@mail.gmail.com>
Message-ID: <CACL+1atq6DES5KfxL1WTHSfM0_53Tj-3PYKhGf8MYryn=1x70Q@mail.gmail.com>

On Fri, Jan 3, 2014 at 2:35 PM, I. Alejandro Fleischer
<iafleischer at gmail.com> wrote:
>
> Sudenly Im having troubles opening files with the idle editor. When I open a
> file it appears in blank, and can not close it anymore.
>
> My OS is ubuntu 13.10 (64 bits) and my python version is 2.7.5.

Maybe something is wrong with a configuration file. Try renaming the
.idlerc directory:

    mv ~/.idlerc ~/.idlerc.bak

From keithwins at gmail.com  Fri Jan  3 21:03:20 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 15:03:20 -0500
Subject: [Tutor] What's in a name?
In-Reply-To: <la67k7$olk$1@ger.gmane.org>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <la67k7$olk$1@ger.gmane.org>
Message-ID: <CAO5ffbaPtzFF23d=Zo0SZRF+fCG0oEdc-okdt-M0F6+A0HSShQ@mail.gmail.com>

On Fri, Jan 3, 2014 at 6:41 AM, Alan Gauld <alan.gauld at btinternet.com>wrote:

> This is off topic but a couple of points about the OOP stuff...
>
>
thanks Alan, this was helpful.



> "If I'm iterating a variable through a series of list names,
> for future processing, I would like to print the name of the
> list the variable is set to in a given moment... "
>
> Remember that variables in Python are just names.
> So we can rewrite your statement as
>
> "If I'm iterating a name through a series of list names, for future
> processing, I would like to print the name of the list the name is set to
> in a given moment... "
>
> And since the list names are just strings we can write:
>
> "If I'm iterating a name through a list of strings, for future processing,
> I would like to print the name in a given moment...
>
> So the answer to your question is just to print the string.
> The real challenge, as we have discovered, is how to access
> the list that is named by the string. And the usual way to
> map strings to objects is via a dictionary not by using eval().
>
>
Here's the thing: I think most of my "problems" go away with better design.
But in case I'm wrong, what I was trying to do, which I would think could
sometimes be helpful, is printing the name of an object along with it's
output/results... I don't think there's any way to do the opposite of
eval(), that is, create a string from an object name. Or am I just missing
something here (I THINK the right way to do this is add, if necessary, and
__name__ method, or at least a .name attribute, to the class... though now
that I think about it I think that still doesn't solve the problem, it
names the class not the instance.

Do you really need the num_xxx variables?
> Using len(xxx_list) is more reliable that depending on your
> code to maintain the values. It may be that you need them
> for a performance optimisation but given that games are
> not normally CPU bound that seems unlikely.
>
>
It was something between performance optimization and historical artifact.
I'm pretty sure the effect of it's optimization was to slow the program
down. It/they are redundant.


>
>          return [tchutes, tladders]  # only one will be != 0
>>
>
> I don't understand the tchutes/tladders stuff? They hold the
> target position or zero (the return comment is wrong BTW since both
> could be zero). Why not just have a single variable called target
> or somesuch? Also if you must return two values its probably better to use
> a tuple rather than a list.
>
>
Oh god, you are airing all my dirty laundry. On each move, the position
might be a chute, or a ladder, or neither. After I use that position to
determine if it's a chute or ladder, it seems like it makes sense to store
that info explicitly, to avoid another dictionary lookup. Probably another
optimization mistake. So if the first returned list entry has a number in
it, it's a chute, and add it to the list of chutes this game traversed, and
same with the second entry and ladder... I suspect I should do this
entirely differently.


>
> Shouldn't the self.position assignment be part of reset()?
>
>
It used to be, but then I realized it's not a state I need to save: I meant
to change it to a local variable.


>
>           while self.position < 100:
>>              gamecandl = self.move()  # [chute, ladder] or [0, 0]
>>              if gamecandl[0] != 0: # populate chutes list
>>                  self.chutes_list.append(gamecandl[0])
>>              if gamecandl[1] != 0:  # populate ladders list
>>                  self.ladders_list.append(gamecandl[1])
>>
>
> Why don't you do this update of the lists in the move() code.
> It's where it logically happens and saves passing back the
> list/tuple and then having to test it here.  This just adds
> extra work.
>
>
Hmm. That seems like a good point. I think it all shifts when I properly
implement the Game() class. Next draft.


>
>           return [step, self.move_count, self.num_chutes,
>> self.num_ladders, self.chutes_list, self.ladders_list]
>>
>
> In OOP you rarely have to return attributes. And since step
> is passed in as an argument the caller already knows. So I
> don't think you really need to return anything here.


Yes, reading this is what helped me see the direction of the next rewrite.
Thanks.


>
> OK, I see now, you are storing the current state values
> after each game. Personally I'd probably create another
> method called (get_stats() or similar and have play() return
> success/failure.
>
>
ooooo.... success or failure. You're edging me towards exception handling.

Then your line above would be:
>
> return [self.get_stats() for i in range(gamecount) if self.play()]
>
> It keeps the purpose of the methods explicit. play() plays the game,
> get_stats() returns the data.
>
> But there is another more OOP approach.
> Create a game instance for each iteration.
> Then collect the instances which then hold the data.
> No need for all the extra arrays, return values, etc.
> It's by using and passing whole *objects* around that
> it is *Object Oriented*. We are trying to move away
> from knowing about the internal data.


Ah, I didn't read this before I figured it out, but I had essentially
exactly this insight. Very satisfying. Thanks!

I think the rest of your comments more or less riff on this, and I
mentioned some similar ideas in a response I already made. It's very
helpful to have them reinforced though! Thanks for your thorough overview.

Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/57406e9b/attachment.html>

From keithwins at gmail.com  Fri Jan  3 22:41:10 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 16:41:10 -0500
Subject: [Tutor] python, speed, game programming
Message-ID: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/1cd57991/attachment-0001.html>

From keithwins at gmail.com  Fri Jan  3 22:53:48 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 16:53:48 -0500
Subject: [Tutor] python, speed, game programming
In-Reply-To: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
Message-ID: <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>

Shoot, sorry for the empty message. Here's what I was going to say:

I am gearing up for the next project (yeah, an eventual end to Chutes &
Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak
but I would expect it easily adapted to QWERTY or anything else.

The basic idea is build a database of the key and response time of every
keystroke, with simultaneous background processing going on, based on a
customizable set of parameters to select the test text in more or less real
time. So for example, I might wish to adjust the interval at which I
revisit old material, to be sure I "get" it without becoming bored by it:
we could call this the repetition interval, and it might well be a function
that increases with time, though it might also be keyed to the speed of
recall... all responses are to be saved long-term for subsequent analysis.

My concern is with speed. This will have to keep up with (somewhat
arbitrarily) fast typing, while doing background processing, with a GUI of
course. This illustrates why I was concerned about the fact that my Chutes
& Ladders game seems to run at the same speed on my 8 y.o. Core 2 Duo and
my 2 y.o. Core I7 with 3-4x as much memory. This WILL require a faster
machine and a more significant share of it's resources, if I develop it in
the direction I am thinking.

I hope Python is a good choice here, though I suppose some modules or
classes or parts will have to be recoded into something faster... Any
thoughts on this will be appreciated, including how to structure it in such
a manner that it might be more portably applied to future versions in
entirely different knowledge realms (music/midi input,
language/vocabulary/audio output, etc).

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/8b4b2942/attachment.html>

From keithwins at gmail.com  Fri Jan  3 23:04:45 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 17:04:45 -0500
Subject: [Tutor] python, speed, game programming
In-Reply-To: <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
Message-ID: <CAO5ffbbRWP2JAHJQFKdU82n1d5UOV0Vq0O_4ehCGfToOzPY6EA@mail.gmail.com>

Just to be clear: this is equal parts learning Python project, prototype
tutorial software project, OOP practice, and the beginning of a more
general inquiry into learning styles/paradigms/parameters... I'm (slowly)
writing some of these ideas up in a separate doc.


On Fri, Jan 3, 2014 at 4:53 PM, Keith Winston <keithwins at gmail.com> wrote:

> Shoot, sorry for the empty message. Here's what I was going to say:
>
> I am gearing up for the next project (yeah, an eventual end to Chutes &
> Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak
> but I would expect it easily adapted to QWERTY or anything else.
>
> The basic idea is build a database of the key and response time of every
> keystroke, with simultaneous background processing going on, based on a
> customizable set of parameters to select the test text in more or less real
> time. So for example, I might wish to adjust the interval at which I
> revisit old material, to be sure I "get" it without becoming bored by it:
> we could call this the repetition interval, and it might well be a function
> that increases with time, though it might also be keyed to the speed of
> recall... all responses are to be saved long-term for subsequent analysis.
>
> My concern is with speed. This will have to keep up with (somewhat
> arbitrarily) fast typing, while doing background processing, with a GUI of
> course. This illustrates why I was concerned about the fact that my Chutes
> & Ladders game seems to run at the same speed on my 8 y.o. Core 2 Duo and
> my 2 y.o. Core I7 with 3-4x as much memory. This WILL require a faster
> machine and a more significant share of it's resources, if I develop it in
> the direction I am thinking.
>
> I hope Python is a good choice here, though I suppose some modules or
> classes or parts will have to be recoded into something faster... Any
> thoughts on this will be appreciated, including how to structure it in such
> a manner that it might be more portably applied to future versions in
> entirely different knowledge realms (music/midi input,
> language/vocabulary/audio output, etc).
>
> --
> Keith
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/65d65b8c/attachment.html>

From jeanpierreda at gmail.com  Fri Jan  3 23:11:21 2014
From: jeanpierreda at gmail.com (Devin Jeanpierre)
Date: Fri, 3 Jan 2014 14:11:21 -0800
Subject: [Tutor] python, speed, game programming
In-Reply-To: <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
Message-ID: <CABicbJ+4X7NkNwZBBjn0yaEgiaJ2opVyReNYspAeOs28joC+jg@mail.gmail.com>

On Fri, Jan 3, 2014 at 1:53 PM, Keith Winston <keithwins at gmail.com> wrote:
> I am gearing up for the next project (yeah, an eventual end to Chutes &
> Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak but
> I would expect it easily adapted to QWERTY or anything else.
>
[snip]
>
> I hope Python is a good choice here, though I suppose some modules or
> classes or parts will have to be recoded into something faster... Any
> thoughts on this will be appreciated, including how to structure it in such
> a manner that it might be more portably applied to future versions in
> entirely different knowledge realms (music/midi input,
> language/vocabulary/audio output, etc).

Modern computers are just so absurdly fast that the overhead Python
has compared to other languages just doesn't matter for the kind of
work you are doing. If you typed at a hundred characters per second
Python could still keep up, unless there's something about your
problem you aren't describing.

-- Devin

From blechnum at fireflyuk.net  Fri Jan  3 23:18:00 2014
From: blechnum at fireflyuk.net (blechnum at fireflyuk.net)
Date: Fri, 03 Jan 2014 22:18:00 +0000
Subject: [Tutor] python problems on android
Message-ID: <52c73718.1e04.1fb4.47cd@fireflyuk.net>



Hi. I wrote a few python programs and had them running on my phone up 
to last september.
Haven't had time to work on them again till now.
Only now, they... don't work !
Not sure why and its very frustrating.

one of the errors is in response to an input request like this

g = input ("type h to use last settings ")

stops the program with this

File <string>, line1, in <module>
NameError: name 'h' is not defined

after I entered h

Will I have to abandon using SL4A and Python and switch to using 
android/java ?



From davea at davea.name  Fri Jan  3 23:54:10 2014
From: davea at davea.name (Dave Angel)
Date: Fri, 03 Jan 2014 17:54:10 -0500
Subject: [Tutor] python problems on android
In-Reply-To: <52c73718.1e04.1fb4.47cd@fireflyuk.net>
References: <52c73718.1e04.1fb4.47cd@fireflyuk.net>
 <52c73718.1e04.1fb4.47cd@fireflyuk.net>
Message-ID: <almarsoft.3794201954544125802@news.gmane.org>

On Fri, 03 Jan 2014 22:18:00 +0000, blechnum at fireflyuk.net wrote:
> one of the errors is in response to an input request like this


> g = input ("type h to use last settings ")


> stops the program with this


> File <string>, line1, in <module>
> NameError: name 'h' is not defined


> after I entered h

Looks to me like you were previously running python 3.x and somehow 
have reverted to 2.x

Add two lines before the input ()

import sys
print (sys.version)

to see what you're using.

-- 
DaveA


From denis.spir at gmail.com  Sat Jan  4 00:12:52 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 04 Jan 2014 00:12:52 +0100
Subject: [Tutor] python, speed, game programming
In-Reply-To: <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
Message-ID: <52C743F4.5000000@gmail.com>

On 01/03/2014 10:53 PM, Keith Winston wrote:
> My concern is with speed. This will have to keep up with (somewhat
> arbitrarily) fast typing, while doing background processing, with a GUI of
> course.

I wouldn't even bother. Try & see, you may be surprised. There are several 
factors at play:
* The core processing in dealing with user input (read, decode, store, queue key 
strokes, etc) will be done by low-level (OS) routines written in C, with only 
thin Python wrappers (which essentially translate from/to python data types).
* Similar point for GUI and/or other user interface layer (less so if you'd use 
a pure python GUI framework, but in general they're also just wrappers over C code).
* The ratio between such low-level processing and actual processing code written 
and executed in python for your application logic is certainly high (as is 
usually the case), unless there is much realtime computation you did not speak 
about.
Anyway, just try and see.

This is similar to how & why python is reputed to be good (read: fast) at 
"number crunching": they are standard libs for that just link to low-level C 
routines which do about all computation, behind the stage, and very few 
application logic remains written *and actually executed* in python (search 
"numpy").

Denis

From wprins at gmail.com  Sat Jan  4 00:48:32 2014
From: wprins at gmail.com (Walter Prins)
Date: Fri, 3 Jan 2014 23:48:32 +0000
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbaPtzFF23d=Zo0SZRF+fCG0oEdc-okdt-M0F6+A0HSShQ@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <la67k7$olk$1@ger.gmane.org>
 <CAO5ffbaPtzFF23d=Zo0SZRF+fCG0oEdc-okdt-M0F6+A0HSShQ@mail.gmail.com>
Message-ID: <CANLXbfB_X+FrJ1R+C2F7mDqZ2uFj2Dm4caDtx5LRb45F32CO2w@mail.gmail.com>

Hi Keith,

On 3 January 2014 20:03, Keith Winston <keithwins at gmail.com> wrote:
>> So the answer to your question is just to print the string.
>> The real challenge, as we have discovered, is how to access
>> the list that is named by the string. And the usual way to
>> map strings to objects is via a dictionary not by using eval().
>
> Here's the thing: I think most of my "problems" go away with better design.
> But in case I'm wrong, what I was trying to do, which I would think could
> sometimes be helpful, is printing the name of an object along with it's
> output/results... I don't think there's any way to do the opposite of
> eval(), that is, create a string from an object name. Or am I just missing
> something here (I THINK the right way to do this is add, if necessary, and
> __name__ method, or at least a .name attribute, to the class... though now
> that I think about it I think that still doesn't solve the problem, it names
> the class not the instance.

Firstly a caveat/disclaimer/apology:  I've not read every post in this
thread in detail, so apologies if some of my comments miss the point
or has otherwise been already made to death.

Secondly, it seems to me you seem perhaps to think of an object's name
as something intrinsic, e.g. an attribute that is (or should be) part
of every object.  Note you should view objects as not having intrinsic
names unless *you* make it so via code.  The names that you associate
to your objects in your program however, are not part of your objects,
instead they live separately in namespaces and do not form part of the
objects themselves.

To belabor the point:  You should distinguish between a) references to
your objects that are "name references" that live in a namespace
somewhere (which some people call variables) and b) other anonymous
references, e.g. just non-name references held by another object (for
example such as that which is held by a list that contains your
object), and c) a potential name attribute or property you might add
to your objects to store some custom name that you'd like to give your
object at runtime (and again, which is therefore quite separate from
and distinct to any variable/namespace references that might also be
referring to your object.).

Generally, if you want an object to have a name, then make an
attribute to represent the name and use that, as you've indeed alluded
to above.  It's not usually the right idea to try and introspect back
to the (possibly many, or none) namespace references referring to your
objects.

Now, having said all that, and though I'm hesitant to even mention
this in fear of muddying the waters and confusing matters by doing so,
it is in fact possible (and with some caveats), to query for and
retrieve all the name references for an object with a bit of querying
of the Python runtime environment (specifically the garbage
collector).  Try this:

---------------
import gc, itertools

def names_of(obj):
    """Try to find the names associated to a given object."""
    #Find dict objects from the garbase collector:
    refs_dicts = (ref for ref in gc.get_referrers(obj) if isinstance(ref, dict))
    #Get a single chained generator for all the iteritems() iterators
in all the dicts
    keyvalue_pairs = itertools.chain.from_iterable(refd.iteritems()
for refd in refs_dicts)
    #Return a list of keys (names) where the value (obj) is the one
we're looking for:
    return [k for k, v in keyvalue_pairs if v is obj]

x = []
y = x
z = [x]

print names_of(z[0])
---------------

As you might expect, the last line outputs the 2 names for the list
initially named "x" above, e.g. ['x', 'y']

As for generating a string representation of an object, by convention
the output of the repr() function is usually supposed to give you a
string _repr_esentation (geddit) that should, if submitted to the
Python interpreter (or eval), give you back an equivalent object to
the one that was passed to repr().  This however is not guaranteed and
you should _NOT_ rely on repr()/eval() if you're trying to
serialise/deserialize your objects, not least due to the security
dangers implied by eval.  Instead, use the pickle module:
http://docs.python.org/2/library/pickle.html

HTH,

Walter

From wprins at gmail.com  Sat Jan  4 00:56:12 2014
From: wprins at gmail.com (Walter Prins)
Date: Fri, 3 Jan 2014 23:56:12 +0000
Subject: [Tutor] What's in a name?
In-Reply-To: <CANLXbfB_X+FrJ1R+C2F7mDqZ2uFj2Dm4caDtx5LRb45F32CO2w@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <la67k7$olk$1@ger.gmane.org>
 <CAO5ffbaPtzFF23d=Zo0SZRF+fCG0oEdc-okdt-M0F6+A0HSShQ@mail.gmail.com>
 <CANLXbfB_X+FrJ1R+C2F7mDqZ2uFj2Dm4caDtx5LRb45F32CO2w@mail.gmail.com>
Message-ID: <CANLXbfD-5-D1bbAjUWX7NAmsanJJumhfJBE0x201rJkPEaD6tw@mail.gmail.com>

Hi,

The code in my last post got line wrapped which will break if directly
tried out.  To avoid possible confusion I paste a version below with
shorter lines which should avoid the problem:


import gc, itertools

def names_of(obj):
    """Try to find the names associated to a given object."""
    #Find dict objects from the garbage collector:
    refs_dicts = (ref for ref in gc.get_referrers(obj)
                  if isinstance(ref, dict))
    #Get a single chained generator for all the iteritems() iterators
    #in all the dicts
    keyvalue_pairs = itertools.chain.from_iterable(
                        refd.iteritems() for refd in refs_dicts)
    #Return a list of keys (names) where the value (obj) is the one
    #we're looking for:
    return [k for k, v in keyvalue_pairs if v is obj]

x = []
y = x
z = [x]

print names_of(z[0])

From blechnum at fireflyuk.net  Sat Jan  4 01:26:59 2014
From: blechnum at fireflyuk.net (blechnum at fireflyuk.net)
Date: Sat, 04 Jan 2014 00:26:59 +0000
Subject: [Tutor] python problems on android
Message-ID: <52c75553.1e04.bf8.2779@fireflyuk.net>


Thanks Dave.

I was using 3.2.2 and uninstalled it earlier as it was giving me 
strange messages.
Just reinstalled to remind myself what these were.

here goes,

WARNING: linker: libpython3.2m.so has text relocations this is wasting 
memory and is a security risk. Please fix

the warning message repeats replacing the module name with several 
others like array.cpython-32m.so
It ran my program with the same Name Error:name l is not defined 
problem as before

The error I posted was using 2.6.2

So my program crashes on both 2 and 3

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140104/b3b4d199/attachment.html>

From keithwins at gmail.com  Sat Jan  4 01:31:15 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 19:31:15 -0500
Subject: [Tutor] python, speed, game programming
In-Reply-To: <52C743F4.5000000@gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
 <52C743F4.5000000@gmail.com>
Message-ID: <CAO5ffbYhVFg25bDL14QR-pqU-BWH960H1MzMRrWfeN+nbdOnAQ@mail.gmail.com>

Okay, thanks, I'll probably be proceeding over the next few weeks, as I
finish up my Chutes & Ladders project... I think I have to do a bit more
code/manual reading in proportion to my coding for a bit, also. Thanks for
the insights.

K


On Fri, Jan 3, 2014 at 6:12 PM, spir <denis.spir at gmail.com> wrote:

> On 01/03/2014 10:53 PM, Keith Winston wrote:
>
>> My concern is with speed. This will have to keep up with (somewhat
>> arbitrarily) fast typing, while doing background processing, with a GUI of
>> course.
>>
>
> I wouldn't even bother. Try & see, you may be surprised. There are several
> factors at play:
> * The core processing in dealing with user input (read, decode, store,
> queue key strokes, etc) will be done by low-level (OS) routines written in
> C, with only thin Python wrappers (which essentially translate from/to
> python data types).
> * Similar point for GUI and/or other user interface layer (less so if
> you'd use a pure python GUI framework, but in general they're also just
> wrappers over C code).
> * The ratio between such low-level processing and actual processing code
> written and executed in python for your application logic is certainly high
> (as is usually the case), unless there is much realtime computation you did
> not speak about.
> Anyway, just try and see.
>
> This is similar to how & why python is reputed to be good (read: fast) at
> "number crunching": they are standard libs for that just link to low-level
> C routines which do about all computation, behind the stage, and very few
> application logic remains written *and actually executed* in python (search
> "numpy").
>
> Denis
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/2f2494dd/attachment.html>

From keithwins at gmail.com  Sat Jan  4 01:25:03 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 19:25:03 -0500
Subject: [Tutor] What's in a name?
In-Reply-To: <CANLXbfD-5-D1bbAjUWX7NAmsanJJumhfJBE0x201rJkPEaD6tw@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <la67k7$olk$1@ger.gmane.org>
 <CAO5ffbaPtzFF23d=Zo0SZRF+fCG0oEdc-okdt-M0F6+A0HSShQ@mail.gmail.com>
 <CANLXbfB_X+FrJ1R+C2F7mDqZ2uFj2Dm4caDtx5LRb45F32CO2w@mail.gmail.com>
 <CANLXbfD-5-D1bbAjUWX7NAmsanJJumhfJBE0x201rJkPEaD6tw@mail.gmail.com>
Message-ID: <CAO5ffbZp-FtkDW8KxkyA1FRiLm53hpK1QZcFUp=f3EWDGLq4FA@mail.gmail.com>

Thanks Walter, I think I've got the lay of the land roughly, but my grasp
is still light and imperfect. I'm pretty confident I shouldn't be doing
anything like what you're describing for the level of coding I'm doing, but
it's interesting to see the approach.

Keith



On Fri, Jan 3, 2014 at 6:56 PM, Walter Prins <wprins at gmail.com> wrote:

> Hi,
>
> The code in my last post got line wrapped which will break if directly
> tried out.  To avoid possible confusion I paste a version below with
> shorter lines which should avoid the problem:
>
>
> import gc, itertools
>
> def names_of(obj):
>     """Try to find the names associated to a given object."""
>     #Find dict objects from the garbage collector:
>     refs_dicts = (ref for ref in gc.get_referrers(obj)
>                   if isinstance(ref, dict))
>     #Get a single chained generator for all the iteritems() iterators
>     #in all the dicts
>     keyvalue_pairs = itertools.chain.from_iterable(
>                         refd.iteritems() for refd in refs_dicts)
>     #Return a list of keys (names) where the value (obj) is the one
>     #we're looking for:
>     return [k for k, v in keyvalue_pairs if v is obj]
>
> x = []
> y = x
> z = [x]
>
> print names_of(z[0])
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/82fe06a5/attachment-0001.html>

From jeanpierreda at gmail.com  Sat Jan  4 01:41:31 2014
From: jeanpierreda at gmail.com (Devin Jeanpierre)
Date: Fri, 3 Jan 2014 16:41:31 -0800
Subject: [Tutor] python problems on android
In-Reply-To: <52c75553.1e04.bf8.2779@fireflyuk.net>
References: <52c75553.1e04.bf8.2779@fireflyuk.net>
Message-ID: <CABicbJJPiJqf488rDf=STwFYs3ob90ON_szvCMZ7n4NWa_ZbdQ@mail.gmail.com>

On Fri, Jan 3, 2014 at 4:26 PM,  <blechnum at fireflyuk.net> wrote:
> Thanks Dave.

Your email doesn't appear to be in response to anything. I think your
email client is broken, and you should switch to a different one.

-- Devin

From kfiresmith at gmail.com  Fri Jan  3 20:51:47 2014
From: kfiresmith at gmail.com (Kodiak Firesmith)
Date: Fri, 3 Jan 2014 14:51:47 -0500
Subject: [Tutor] idle problem
In-Reply-To: <CAHNAVNt_K44pShKFwjKubk2t-Lq3NTzSb6YB55Fp_6OTwUePPw@mail.gmail.com>
References: <CAHNAVNt_K44pShKFwjKubk2t-Lq3NTzSb6YB55Fp_6OTwUePPw@mail.gmail.com>
Message-ID: <CALh5p2vH5pFqeKvCOwfy4jeYTX6B87d_t=M9=0B86_TkA+9CdQ@mail.gmail.com>

Hello Alejandro!

Try running idle via a terminal and see if it's throwing out any error
information.  (-d switch for dubug)

I've moved on to a mix between PyCharm and Vim depending on how big of a
"project" I'm working on, but I still have idle installed so I can probably
help a bit more if there's more details to be had.

 - Kodiak


On Fri, Jan 3, 2014 at 2:35 PM, I. Alejandro Fleischer <
iafleischer at gmail.com> wrote:

> Hello to everyone,
>
> Sudenly Im having troubles opening files with the idle editor. When I open
> a file it appears in blank, and can not close it anymore.
>
> My OS is ubuntu 13.10 (64 bits) and my python version is 2.7.5.
>
> Regards,
>
> Igor
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/dac7edcd/attachment.html>

From kfiresmith at gmail.com  Fri Jan  3 21:11:29 2014
From: kfiresmith at gmail.com (Kodiak Firesmith)
Date: Fri, 3 Jan 2014 15:11:29 -0500
Subject: [Tutor] idle problem
In-Reply-To: <CAHNAVNu41cROY0ygOWrRTO08EOPr78-Mi_3pz=_vnPMPkyKcpA@mail.gmail.com>
References: <CAHNAVNt_K44pShKFwjKubk2t-Lq3NTzSb6YB55Fp_6OTwUePPw@mail.gmail.com>
 <CALh5p2sSbDNZJYFYhEiXzC4=PykZ0FA-4cghtW2t+ej=BAYmjQ@mail.gmail.com>
 <CAHNAVNu41cROY0ygOWrRTO08EOPr78-Mi_3pz=_vnPMPkyKcpA@mail.gmail.com>
Message-ID: <CALh5p2uAZRqtXQFtkSPGaJLYGwLsf4=rSYt6qGvY5MtRcc5Vmg@mail.gmail.com>

Well, run Idle in the foreground for now (skip the trailing '&'), and try
'idle some_project.py'; that should open the project in the editor window,
as well as opening a python shell window.  The project (module) won't
actually run until you hit 'Run' -> 'Run Module' in the editor (not the
shell) window.[image: Inline image 1]


On Fri, Jan 3, 2014 at 2:58 PM, I. Alejandro Fleischer <
iafleischer at gmail.com> wrote:

> Thank you Kodiak!!!
>
> when I open from terminal idle , appears the first weird thing look at
> picture 1
> when I close (or try to close the window appears the error message) look
> picture 2.
>
> Alejandro
>
>
>
> 2014/1/3 Kodiak Firesmith <kfiresmith at gmail.com>
>
>> Hello Alejandro!
>>
>> Try running idle via a terminal and see if it's throwing out any error
>> information.  (-d switch for dubug)
>>
>> I've moved on to a mix between PyCharm and Vim depending on how big of a
>> "project" I'm working on.
>>
>>  - Kodiak
>>
>>
>> On Fri, Jan 3, 2014 at 2:35 PM, I. Alejandro Fleischer <
>> iafleischer at gmail.com> wrote:
>>
>>> Hello to everyone,
>>>
>>> Sudenly Im having troubles opening files with the idle editor. When I
>>> open a file it appears in blank, and can not close it anymore.
>>>
>>> My OS is ubuntu 13.10 (64 bits) and my python version is 2.7.5.
>>>
>>> Regards,
>>>
>>> Igor
>>>
>>> _______________________________________________
>>> Tutor maillist  -  Tutor at python.org
>>> To unsubscribe or change subscription options:
>>> https://mail.python.org/mailman/listinfo/tutor
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/5c9d12e5/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: alehandro.png
Type: image/png
Size: 52659 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/5c9d12e5/attachment-0001.png>

From rogershaw39 at hotmail.com  Fri Jan  3 22:12:11 2014
From: rogershaw39 at hotmail.com (Roger)
Date: Fri, 3 Jan 2014 21:12:11 -0000
Subject: [Tutor] python problems on android
Message-ID: <DUB121-DS1743B7B5A188D5A2F3B864A5CA0@phx.gbl>

Hi. I wrote a few python programs and had them running on my phone up to last september.
Haven't had time to work on them again till now.
Only now, they... don't work !
Not sure why and its very frustrating.

one of the errors is in response to an input request like this

g = input ("type h to use last settings ") 

stops the program with this

File <string>, line1, in <module>
NameError: name 'h' is not defined

after I entered h

Will I have to abandon using SL4A and Python and switch to using android/java ? 





-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/cb0fec36/attachment.html>

From dyoo at hashcollision.org  Sat Jan  4 02:02:20 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 3 Jan 2014 17:02:20 -0800
Subject: [Tutor] python problems on android
In-Reply-To: <DUB121-DS1743B7B5A188D5A2F3B864A5CA0@phx.gbl>
References: <DUB121-DS1743B7B5A188D5A2F3B864A5CA0@phx.gbl>
Message-ID: <CAGZAPF6QzU0X_tqTYmgQYXs+EEhf2Lmp20N1BO0WjeS8ZvmxfQ@mail.gmail.com>

Hi Roger,

Check whether or not you are running Python 3 or Python 2.  I strongly
suspect you should be using 3, but have run it as a Python 2 program by
accident.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/30ece408/attachment.html>

From alan.gauld at btinternet.com  Sat Jan  4 02:04:10 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 04 Jan 2014 01:04:10 +0000
Subject: [Tutor] idle problem
In-Reply-To: <CAHNAVNt_K44pShKFwjKubk2t-Lq3NTzSb6YB55Fp_6OTwUePPw@mail.gmail.com>
References: <CAHNAVNt_K44pShKFwjKubk2t-Lq3NTzSb6YB55Fp_6OTwUePPw@mail.gmail.com>
Message-ID: <la7mlu$aic$1@ger.gmane.org>

On 03/01/14 19:35, I. Alejandro Fleischer wrote:

> Sudenly Im having troubles opening files with the idle editor. When I
> open a file it appears in blank, and can not close it anymore.

How are you opening it?

How do you run IDLE?
How do you open a file?
What does the 'blank' window display as a title?


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Sat Jan  4 02:17:26 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 04 Jan 2014 01:17:26 +0000
Subject: [Tutor] python, speed, game programming
In-Reply-To: <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
Message-ID: <la7neq$mbl$1@ger.gmane.org>

On 03/01/14 21:53, Keith Winston wrote:

> Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak
> but I would expect it easily adapted to QWERTY or anything else.
> ...
>
> My concern is with speed. This will have to keep up with (somewhat
> arbitrarily) fast typing,

Lets see. The speed record for touch typing is around 150 wpm with 
average word being about 5 chars, so a speed of about 750 cpm
or 12.5cps That's about 80ms between letters.

Python on a modern PC can probably execute around 100k lines
of code(*) per second or 100 per millisecond. That's 8k lines
executed between each keypress for the worlds fastest typist.

I used  to use a typing tutor that was written in old GW Basic
on the original IBM PC (speed 4.7MHz) and it had no problem
analyzing my stats (albeit at a modest 40-50 wpm).

I'd worry about speed after you find you need to.

(*)Caveat: I haven't tried any kind of objective test and
of course some Python 'lines' are equal to many
lines of simpler languages - think list comprehensions.
But in practice I still don't think you will have a
big problem.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From keithwins at gmail.com  Sat Jan  4 02:38:47 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 20:38:47 -0500
Subject: [Tutor] python, speed, game programming
In-Reply-To: <la7neq$mbl$1@ger.gmane.org>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
 <la7neq$mbl$1@ger.gmane.org>
Message-ID: <CAO5ffbZKBUWmaQmDcA7QeHmpRLKpezOdP995tjtiYpR=wDJiVA@mail.gmail.com>

Just to be clear, what I'm asking this typing tutor to do is vastly more
than normal, albeit still not seemingly very much. In most programs, they
give you a sentence or paragraph to type, and then time how long it takes.
I'm talking about timing every keypress, and modifying the text stream
based on that. The thing that put me on edge was noticing that my simple
Chutes & Ladders game doesn't go ANY faster on a machine that benchmarks
perhaps 1000 times faster than another...

Keith


On Fri, Jan 3, 2014 at 8:17 PM, Alan Gauld <alan.gauld at btinternet.com>wrote:

> On 03/01/14 21:53, Keith Winston wrote:
>
>  Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak
>> but I would expect it easily adapted to QWERTY or anything else.
>> ...
>>
>>
>> My concern is with speed. This will have to keep up with (somewhat
>> arbitrarily) fast typing,
>>
>
> Lets see. The speed record for touch typing is around 150 wpm with average
> word being about 5 chars, so a speed of about 750 cpm
> or 12.5cps That's about 80ms between letters.
>
> Python on a modern PC can probably execute around 100k lines
> of code(*) per second or 100 per millisecond. That's 8k lines
> executed between each keypress for the worlds fastest typist.
>
> I used  to use a typing tutor that was written in old GW Basic
> on the original IBM PC (speed 4.7MHz) and it had no problem
> analyzing my stats (albeit at a modest 40-50 wpm).
>
> I'd worry about speed after you find you need to.
>
> (*)Caveat: I haven't tried any kind of objective test and
> of course some Python 'lines' are equal to many
> lines of simpler languages - think list comprehensions.
> But in practice I still don't think you will have a
> big problem.
>
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> 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
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/ccc4d6cb/attachment.html>

From keithwins at gmail.com  Sat Jan  4 02:43:07 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 20:43:07 -0500
Subject: [Tutor] python, speed, game programming
In-Reply-To: <CAO5ffbZKBUWmaQmDcA7QeHmpRLKpezOdP995tjtiYpR=wDJiVA@mail.gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
 <la7neq$mbl$1@ger.gmane.org>
 <CAO5ffbZKBUWmaQmDcA7QeHmpRLKpezOdP995tjtiYpR=wDJiVA@mail.gmail.com>
Message-ID: <CAO5ffbbhCXXMRNBZdjgSk8N8nUm_-N9yOG2=xfk6whH43cDTpQ@mail.gmail.com>

Truth in advertising: I just realized a Core I7 only benchmarks about 10x
faster than a Core 2 Duo, using Passmark. Wow, something like 6 years newer
and only 10 times? Anyway, I'd STILL expect to see some of that in the
program performance, though maybe once I get it ironed out it will be a
little sleeker...

Keith


On Fri, Jan 3, 2014 at 8:38 PM, Keith Winston <keithwins at gmail.com> wrote:

> Just to be clear, what I'm asking this typing tutor to do is vastly more
> than normal, albeit still not seemingly very much. In most programs, they
> give you a sentence or paragraph to type, and then time how long it takes.
> I'm talking about timing every keypress, and modifying the text stream
> based on that. The thing that put me on edge was noticing that my simple
> Chutes & Ladders game doesn't go ANY faster on a machine that benchmarks
> perhaps 1000 times faster than another...
>
> Keith
>
>
> On Fri, Jan 3, 2014 at 8:17 PM, Alan Gauld <alan.gauld at btinternet.com>wrote:
>
>> On 03/01/14 21:53, Keith Winston wrote:
>>
>>  Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak
>>> but I would expect it easily adapted to QWERTY or anything else.
>>> ...
>>>
>>>
>>> My concern is with speed. This will have to keep up with (somewhat
>>> arbitrarily) fast typing,
>>>
>>
>> Lets see. The speed record for touch typing is around 150 wpm with
>> average word being about 5 chars, so a speed of about 750 cpm
>> or 12.5cps That's about 80ms between letters.
>>
>> Python on a modern PC can probably execute around 100k lines
>> of code(*) per second or 100 per millisecond. That's 8k lines
>> executed between each keypress for the worlds fastest typist.
>>
>> I used  to use a typing tutor that was written in old GW Basic
>> on the original IBM PC (speed 4.7MHz) and it had no problem
>> analyzing my stats (albeit at a modest 40-50 wpm).
>>
>> I'd worry about speed after you find you need to.
>>
>> (*)Caveat: I haven't tried any kind of objective test and
>> of course some Python 'lines' are equal to many
>> lines of simpler languages - think list comprehensions.
>> But in practice I still don't think you will have a
>> big problem.
>>
>>
>> --
>> Alan G
>> Author of the Learn to Program web site
>> http://www.alan-g.me.uk/
>> 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
>>
>
>
>
> --
> Keith
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/835ed880/attachment-0001.html>

From keithwins at gmail.com  Sat Jan  4 03:53:51 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 21:53:51 -0500
Subject: [Tutor] simple arg problem
Message-ID: <CAO5ffbbHkob+jw+hRh9YozCVkxXhjTpnJTNhqnKOCd7qS6HHjQ@mail.gmail.com>

I'm trying to rewrite/reshuffle my Chutes & Ladders code, which I generally
find more confusing than writing anew.

Anyway, I've got a method that seems like it calls for one argument but...

    def populate(self, gamecount1):
        """populate candl_array with a set of games"""

(method of a new class CandL_Array, which contains a list called
candl_array)

Every time I run it with


-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/67a2ebe3/attachment.html>

From keithwins at gmail.com  Sat Jan  4 03:56:25 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 21:56:25 -0500
Subject: [Tutor] simple arg problem
In-Reply-To: <CAO5ffbbHkob+jw+hRh9YozCVkxXhjTpnJTNhqnKOCd7qS6HHjQ@mail.gmail.com>
References: <CAO5ffbbHkob+jw+hRh9YozCVkxXhjTpnJTNhqnKOCd7qS6HHjQ@mail.gmail.com>
Message-ID: <CAO5ffbbSs150eE-o-rLokG4Y090OfLSd-0YRtZ3F30mwRU80GQ@mail.gmail.com>

gmail is driving me crazy. Anyway, every time I run it with:

if __name__ == "__main__":
    tarray = CandL_Array
    tarray.populate(100)

I get an error

Traceback (most recent call last):
  File "/home/keithwins/Dropbox/Python/CandL8.py", line 127, in <module>
    tarray.populate(100)
TypeError: populate() missing 1 required positional argument: 'gamecount1'
>>>

Which seems to say it wants another argument, but I am in the habit of not
counting the self argument... I thought I understood that. I'm sure it's
something obvious, but I've been staring at it for hours. This is going to
be embarrassing...



On Fri, Jan 3, 2014 at 9:53 PM, Keith Winston <keithwins at gmail.com> wrote:

> I'm trying to rewrite/reshuffle my Chutes & Ladders code, which I
> generally find more confusing than writing anew.
>
> Anyway, I've got a method that seems like it calls for one argument but...
>
>     def populate(self, gamecount1):
>         """populate candl_array with a set of games"""
>
> (method of a new class CandL_Array, which contains a list called
> candl_array)
>
> Every time I run it with
>
>
> --
> Keith
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/bc430ce9/attachment.html>

From eryksun at gmail.com  Sat Jan  4 04:14:57 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 3 Jan 2014 22:14:57 -0500
Subject: [Tutor] simple arg problem
In-Reply-To: <CAO5ffbbSs150eE-o-rLokG4Y090OfLSd-0YRtZ3F30mwRU80GQ@mail.gmail.com>
References: <CAO5ffbbHkob+jw+hRh9YozCVkxXhjTpnJTNhqnKOCd7qS6HHjQ@mail.gmail.com>
 <CAO5ffbbSs150eE-o-rLokG4Y090OfLSd-0YRtZ3F30mwRU80GQ@mail.gmail.com>
Message-ID: <CACL+1atd9MZF10cQRYpnt_ajK+2EgU9uzXPjDA40xtY-yNP3xA@mail.gmail.com>

On Fri, Jan 3, 2014 at 9:56 PM, Keith Winston <keithwins at gmail.com> wrote:
>
> if __name__ == "__main__":
>     tarray = CandL_Array
>     tarray.populate(100)
>
> I get an error
>
> Traceback (most recent call last):
>   File "/home/keithwins/Dropbox/Python/CandL8.py", line 127, in <module>
>     tarray.populate(100)
> TypeError: populate() missing 1 required positional argument: 'gamecount1'
>>>>
>
> Which seems to say it wants another argument, but I am in the habit of not
> counting the self argument... I thought I understood that. I'm sure it's
> something obvious, but I've been staring at it for hours. This is going to
> be embarrassing...

You've assigned the class to `tarray` instead of assigning an instance
of the class. Forgetting to call() is a common mistake.

From keithwins at gmail.com  Sat Jan  4 04:23:28 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 22:23:28 -0500
Subject: [Tutor] simple arg problem
In-Reply-To: <CACL+1atd9MZF10cQRYpnt_ajK+2EgU9uzXPjDA40xtY-yNP3xA@mail.gmail.com>
References: <CAO5ffbbHkob+jw+hRh9YozCVkxXhjTpnJTNhqnKOCd7qS6HHjQ@mail.gmail.com>
 <CAO5ffbbSs150eE-o-rLokG4Y090OfLSd-0YRtZ3F30mwRU80GQ@mail.gmail.com>
 <CACL+1atd9MZF10cQRYpnt_ajK+2EgU9uzXPjDA40xtY-yNP3xA@mail.gmail.com>
Message-ID: <CAO5ffbZ31kyOEeYuF7hq=tdWkRq=CCO6ZqzYrH4MyuWH0zyvcA@mail.gmail.com>

Ah, more briefly: parens. Wow, okay then. Thanks.


On Fri, Jan 3, 2014 at 10:14 PM, eryksun <eryksun at gmail.com> wrote:

> On Fri, Jan 3, 2014 at 9:56 PM, Keith Winston <keithwins at gmail.com> wrote:
> >
> > if __name__ == "__main__":
> >     tarray = CandL_Array
> >     tarray.populate(100)
> >
> > I get an error
> >
> > Traceback (most recent call last):
> >   File "/home/keithwins/Dropbox/Python/CandL8.py", line 127, in <module>
> >     tarray.populate(100)
> > TypeError: populate() missing 1 required positional argument:
> 'gamecount1'
> >>>>
> >
> > Which seems to say it wants another argument, but I am in the habit of
> not
> > counting the self argument... I thought I understood that. I'm sure it's
> > something obvious, but I've been staring at it for hours. This is going
> to
> > be embarrassing...
>
> You've assigned the class to `tarray` instead of assigning an instance
> of the class. Forgetting to call() is a common mistake.
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/3904ac9c/attachment.html>

From breamoreboy at yahoo.co.uk  Sat Jan  4 05:14:04 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sat, 04 Jan 2014 04:14:04 +0000
Subject: [Tutor] python, speed, game programming
In-Reply-To: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
Message-ID: <la81p8$fp6$1@ger.gmane.org>

On 03/01/2014 21:41, Keith Winston wrote:
> --
> Keith
>

Frankly I think you're lining up to jump fences when you're actually 
riding on the flat :)

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

Mark Lawrence


From keithwins at gmail.com  Sat Jan  4 05:38:07 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 23:38:07 -0500
Subject: [Tutor] python, speed, game programming
In-Reply-To: <la81p8$fp6$1@ger.gmane.org>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <la81p8$fp6$1@ger.gmane.org>
Message-ID: <CAO5ffbZK45NxXKzamGzA1HSZzmozGmLnHSmBW5qh1T2b5BCBvg@mail.gmail.com>

On Fri, Jan 3, 2014 at 11:14 PM, Mark Lawrence <breamoreboy at yahoo.co.uk>wrote:

> On 03/01/2014 21:41, Keith Winston wrote:
>
>> --
>> Keith
>>
>>
> Frankly I think you're lining up to jump fences when you're actually
> riding on the flat :)
>

Fair enough,  but I am thinking of the next project as a long-term
dabbling: hopefully my abilities will rise to my  concept... I guess I'm
about 3 weeks into Python (and OOP) so far, of course my ability to focus
on it will depend on work and other pressures, but I'm amazed at how
accessible this language is. Anyway, thanks to you and everyone who've
helped me as I crawl on the flat... this group has been way more than
invaluable.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/0c910477/attachment-0001.html>

From steve at pearwood.info  Sat Jan  4 05:45:33 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 4 Jan 2014 15:45:33 +1100
Subject: [Tutor] simple arg problem
In-Reply-To: <CAO5ffbbSs150eE-o-rLokG4Y090OfLSd-0YRtZ3F30mwRU80GQ@mail.gmail.com>
References: <CAO5ffbbHkob+jw+hRh9YozCVkxXhjTpnJTNhqnKOCd7qS6HHjQ@mail.gmail.com>
 <CAO5ffbbSs150eE-o-rLokG4Y090OfLSd-0YRtZ3F30mwRU80GQ@mail.gmail.com>
Message-ID: <20140104044532.GQ29356@ando>

On Fri, Jan 03, 2014 at 09:56:25PM -0500, Keith Winston wrote:
> gmail is driving me crazy. Anyway, every time I run it with:
> 
> if __name__ == "__main__":
>     tarray = CandL_Array
>     tarray.populate(100)
> 
> I get an error
> 
> Traceback (most recent call last):
>   File "/home/keithwins/Dropbox/Python/CandL8.py", line 127, in <module>
>     tarray.populate(100)
> TypeError: populate() missing 1 required positional argument: 'gamecount1'
> >>>

Eryksun has already solved your immediate problem, but I'd like to point 
out that the above has a couple of code smells.

Are you familiar with the concept of a code smell? Code which smells 
wrong might not be wrong, but it's worth giving it a good hard long look 
just to be sure. Like Grandma used to say about your nappies, "If it 
stinks, change it", code smells usually suggest there's a problem with 
the code.

http://www.codinghorror.com/blog/2006/05/code-smells.html

Like parmesan and blue cheeses, or durian fruit, there are a few 
exceptions, but normally code is like food: it only smells bad when it 
has gone off. You should never write smelly code without giving it a 
good, hard look.

Anyway, back to your code... you have a class CandL_Array which 
apparently you call with no arguments. If it needed arguments, you 
wouldn't have made the error you did, which is to forget to include 
parentheses:

# No
tarray = CandL_Array  # makes tarray an alias to the class

# Yes
tarray = CandL_Array()  # makes tarray an instance of the class


If CandL_Array() needed arguments, you wouldn't have forgotten the round 
brackets, and wouldn't have got the error you did. So there's a little 
whiff of a smell right there... why does the class not take any 
arguments? That suggests that every instance it creates is exactly the 
same as every other instance. That's not necessarily wrong, but it is a 
little bit whiffy.

But then there's the next line:

tarray.populate(100)

Apparently, and I'm reading between the lines here, once you create the 
CandL_Array instance, you can't use it until you populate it. If I'm 
right, that's pretty smelly. That means you have errors like this:

tarray = CandL_Array()  # Initialise an instance.
tarray.play_game()  # or something, you don't show that part of the code


which blows up in your face because you forgot to call populate first. 
That's ugly, stinking code. Imagine if you had to write code like this:

x = float("12.345")
x.prepare()  # Make the float ready to use
y = x + 1.0  # Now we can use it!

Yuck.

Most of the time, creating an instance should do everything needed to 
prepare it for use. I suspect that your game is no exception. If you 
need to call some method to make the instance ready to use, then the 
constructor __new__ or initialiser __init__ should do so.

You don't even have to get rid of the populate method. You just need 
to change this:

class CandL_Array:
    def __init__(self):
        ...
    def populate(self, size):
        ...


to this:

class CandL_Array:
    def __init__(self, size):
        ...
        self.populate(size)
    def populate(self, size):
        ...


and change this:

tarray = CandL_Array()
tarray.populate(100)


to this:

tarray = CandL_Array(100)



-- 
Steven

From keithwins at gmail.com  Sat Jan  4 05:47:49 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 23:47:49 -0500
Subject: [Tutor] More or less final Chutes & Ladders
Message-ID: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>

Here is what I think will be about the final version of C and L. I
rearranged it quite a bit (into 2 classes), fixed a bug or two, and
generally cleaned it up a bit. I haven't really polished it, but hopefully
it will be less difficult to read... which is to say, if anyone wants to go
through it AGAIN (at your leisure) I would appreciate comments on style,
etc.

Probably the biggest change is that I added a result() method to the
ChutesAndLadders class, that returns a list of the pertinent attributes of
each game (to be compiled into the array of games results that CandL_Array
class is all about).

Anyway, I sort of need to get off this since I need to do a lot more
reading on this language, though I may be back with early drafts of my
typing tutor before long... we'll see how that goes.

-- 
Keith

""" Chutes & Ladders Simulation
    Simulates a number of games of Chutes & Ladders (Snakes & Ladders).
    Chutes & Ladders are separate dictionaries to allow tracking of
separate stats.

    Gathers the results into a list of lists of individual game results
    in the form (per game) of [game_no, moves, [chutes], [ladders]]

"""

import random
from timer2 import timer
from statistics import * # from whence comes mean, variance, stdev


# Landing on a chute causes one to slide down to the corresponding value.
chutes = {16: 6, 47: 26, 49: 11, 56: 53, 62: 19, 64: 60, 87: 24, 93: 73,
95: 75, 98:78}

# Landing on a ladder (key) causes one to climb up to the corresponding
value.
ladders = {1: 38, 4: 14, 9: 31, 21: 42, 28: 84, 36: 44, 51: 67, 71: 91,
80:100}

class ChutesAndLadders:
    """Game class for Chutes & Ladders."""

    def __init__(self):
        self.reset()

    def reset(self):
        self.position = 0
        self.game_number = 0
        self.move_count = 0
        self.chutes_list = []
        self.ladders_list = []

    def results(self):
        return [self.game_number, self.move_count, self.chutes_list,
self.ladders_list]

#    @timer
    def move(self):
        """Single move, with chutes, ladders, & out of bounds.
        Primary action is to move self.position, but returns a list
        that consists of either the chute or ladder if landed on, if either
        """

        roll = random.randint(1,6)
        self.move_count += 1
        self.position += roll
        if self.position in chutes:
            self.chutes_list.append(self.position)
            self.position = chutes[self.position]
        elif self.position in ladders:
            self.ladders_list.append(self.position)
            self.position = ladders[self.position]
        elif self.position > 100:  # move doesn't count, have to land
exactly
            self.position -= roll
        return

#    @timer
    def play(self, game_no):
        """Single game"""

        self.reset()
        self.game_number = game_no
        while self.position < 100:
            self.move()
        return

class CandL_Array:
    """ Create & analyze an array of CandL games """

    candl_array = []
    def __init__(self):
        self.candl_array = []

#    @timer
    def populate(self, gamecount1):
        """populate candl_array with a set of games"""

        tgame = ChutesAndLadders()
        for i in range(gamecount1):
            tgame.play(i)
            self.candl_array.append(tgame.results())

    def print_stuff(self):
        self.print_gameset_stats(self.candl_array)
        self.print_candl_info(self.candl_array)

    def print_gameset_stats(self, garray):
        print("Total number of games: ", len(garray))
        print("   Moves        Chutes        Ladders")
        for func in [mean, max, min, stdev]:
            print("{moves:9.2f} {chutes:12.2f} {ladders:13.2f}
{fname}".format(
                moves=func(tgset[1] for tgset in garray),
                chutes=func(len(tgset[2]) for tgset in garray),
                ladders=func(len(tgset[3]) for tgset in garray),
                fname=func.__name__
                ))

    def print_candl_info(self, garray):
        """ Create two dictionaries with the same keys as chutes & ladders,
        but with the total number of times each c or l is traversed (in the
entire gameset)
        as the values. Then, print them. """

        self.chute_nums, self.ladder_nums = dict(chutes), dict(ladders)
        self.summarize_game("chutes", self.chute_nums, 2, garray)
        self.summarize_game("ladders", self.ladder_nums, 3, garray)

    def summarize_game(self, game_name, game_nums, game_index, garray):

        tgame_nums = game_nums
        for i in tgame_nums.keys(): game_nums[i] = 0

        for corl in tgame_nums:
            for game in garray:
                tgame_nums[corl] += game[game_index].count(corl)
        print("total ", game_name, "= ", sum(tgame_nums.values()))

"""   def timing_report():

    print("game.total, count = ", p1.game.total, p1.game.count)
    print("move.total, count = ", p1.move.total, p1.move.count)
"""

def run_CandL(gamecount):
    tarray = CandL_Array()
    tarray.populate(gamecount)
    tarray.print_stuff()

if __name__ == "__main__":
    run_CandL(100)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/a22f9363/attachment.html>

From keithwins at gmail.com  Sat Jan  4 05:57:36 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 3 Jan 2014 23:57:36 -0500
Subject: [Tutor] simple arg problem
In-Reply-To: <20140104044532.GQ29356@ando>
References: <CAO5ffbbHkob+jw+hRh9YozCVkxXhjTpnJTNhqnKOCd7qS6HHjQ@mail.gmail.com>
 <CAO5ffbbSs150eE-o-rLokG4Y090OfLSd-0YRtZ3F30mwRU80GQ@mail.gmail.com>
 <20140104044532.GQ29356@ando>
Message-ID: <CAO5ffbYR5hvNzSeRRufh8rtehuZjTovxZ_qEFU-wpptC_AXVaA@mail.gmail.com>

Hi Steven,

tarray = CandL_Array(100)

Yes, that's definitely better. I'll make that change. Thanks, makes sense.
I'd already posted my "finished" version, so I probably won't repost with
this small change right now.

Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140103/c5a894ca/attachment.html>

From steve at pearwood.info  Sat Jan  4 05:59:19 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 4 Jan 2014 15:59:19 +1100
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
Message-ID: <20140104045919.GR29356@ando>

On Fri, Jan 03, 2014 at 12:29:34AM -0500, Keith Winston wrote:
> Hmm, maybe I stumbled upon at least one approach, turning the problem
> around. Make it something like:
> 
> for i in ["alist", "blist", "clist"]
>     i[3] = "okey dokey "
>     print(eval(i)[3], i)
> 
> Of course I've been staring at this for a while, but as soon as I post I
> find a way... this is my first use of eval()

And now that you've discovered eval(), do yourself a favour and forget 
all about it.

- eval is dangerous. The number one cause of software vulnerabilities 
  (i.e. bugs which can be used by viruses and malware) today is code 
  ejection, which is a fancy way of saying "somebody screwed up with
  eval or the equivalent".

- eval is slow. In Python, at least, using eval("something()") is
  about ten times slower than just calling something(). That's because
  the slow process of parsing and compiling the text into executable
  code takes place at run-time instead of compile-time.

- eval is confusing. While it's possible to use eval in simple, easy
  to understand ways, there's (usually) not much point in that. So 
  eval normally only gets used in ways which are tricky to write and
  tricky to understand.

- There is very little that cannot be done without eval. It is rarely 
  the best solution, and even more rarely the only solution.


My recommendation is, any time you get the urge to use eval in code, 
go take a cold shower until the urge goes away. Exceptions can be made 
for experts and for interactive use at the REPL.

Your code above is probably better written something like this:

for name in ["alist", "blist", "clist"]:
    thelist = vars()[name]
    thelist[3] = "okey dokey "
    print(name, "=", thelist)



-- 
Steven

From keithwins at gmail.com  Sat Jan  4 06:32:19 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 4 Jan 2014 00:32:19 -0500
Subject: [Tutor] What's in a name?
In-Reply-To: <20140104045919.GR29356@ando>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <20140104045919.GR29356@ando>
Message-ID: <CAO5ffbYrLKjzPTOCRg=O7btHd9bSEm2KxJ5ODm48L7X+1-2OPw@mail.gmail.com>

On Fri, Jan 3, 2014 at 11:59 PM, Steven D'Aprano <steve at pearwood.info>wrote:

> thelist = vars()[name]



I see: vars() certainly looks less dangerous than eval(), but I'm guessing
that's still smelly code? I hadn't known about vars() or I probably would
have used it.

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140104/aa3598f5/attachment.html>

From steve at pearwood.info  Sat Jan  4 06:36:57 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 4 Jan 2014 16:36:57 +1100
Subject: [Tutor] Fwd: What's in a name?
In-Reply-To: <CAO5ffbaAAc35c3ps-WmauXKhJ4HRzf87mW-hVJ1k09UT_Tfm6Q@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <la5ll3$tkt$1@ger.gmane.org>
 <CAO5ffbaAAc35c3ps-WmauXKhJ4HRzf87mW-hVJ1k09UT_Tfm6Q@mail.gmail.com>
Message-ID: <20140104053657.GS29356@ando>

On Fri, Jan 03, 2014 at 01:55:29AM -0500, Keith Winston wrote:
[...]
> I want to iterate through a bunch of lists, subsequently printing both list
> members (via indexing, for example) and the name of the list I'm on.

Why? What does this gain you?

Now, it's true that when *debugging code*, being able to see the name of 
the variable and the contents of the variable is useful. But in ordinary 
code, why would you care to print the name of the variable and its 
contents. Who cares what the variable is named?

Debuggers stick all sorts of nasty hooks into the running interpreter in 
order to do this (and much more), and we should all be thankful that (1) 
debuggers exist, (2) that they aren't running by default, and most 
importantly (3) that we don't have to write code like them.

In addition to powerful debuggers, we also have fantastic poor-man's 
debugger called "print":

for name, value in zip(
            'alist blist clist'.split(), [alist, blist, clist]):
    print(name, "=", value)


Yes, it's a little bit messy code. We have to repeat the name of the 
variable twice. But this isn't code that will hang around in the 
finished program. It only need exist for just long enough to debug the 
problem we're having (you are having a problem, I presume?), then, it's 
job done, it's gone. (Be ruthless at deleting code that isn't pulling 
its weight.) And in the meantime, the rest of our code doesn't need to 
use any nasty indirect code, it can just use (say) alist.append(42) 
instead of eval('alist').append(42).

For longer-lasting indirect code, rather than use eval, its better to do 
something like this:

namespace = {
    'alist': [1, 2, 4, 8, 16, 32],
    'blist': ['fe', 'fi', 'fo', 'fum'],
    'clist': [1.5, 2.5, 3.5, 4.5, 5.5, 6.5]
    }

for name, value in namespace.items():
    print(name, "=", value)


eval is a nuclear-powered bulldozer. Don't use it for cracking nuts.


-- 
Steven

From steve at pearwood.info  Sat Jan  4 06:44:59 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 4 Jan 2014 16:44:59 +1100
Subject: [Tutor] Copying [was Re:  What's in a name?]
In-Reply-To: <CAO5ffbZY4JbzS0ygbOtUm8MsmCWeRW_z-NOoxQ=Q6eCAGr0hzQ@mail.gmail.com>
References: <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <CAGZAPF4WG2pKvkQuHCzgokWvQO5JFaf3x53GEmEwsB-vkPqLFQ@mail.gmail.com>
 <CAGZAPF7KFKDGCTempB+Q74E9g=TLt2FS7ADwtBWuOS36BDW_0w@mail.gmail.com>
 <CAO5ffbZY4JbzS0ygbOtUm8MsmCWeRW_z-NOoxQ=Q6eCAGr0hzQ@mail.gmail.com>
Message-ID: <20140104054459.GT29356@ando>

On Fri, Jan 03, 2014 at 01:53:42PM -0500, Keith Winston wrote:

> That's what I meant to do: make a copy when I wrote chute_nums = chutes. So
> I should have passed chute_nums to summarize_game, but it still wouldn't
> work (because it's not a copy).

Python never makes a copy of objects when you pass them to a function or 
assign them to a name. If you want a copy, you have to copy them 
yourself:

import copy

acopy = copy.copy(something)


ought to work for just about anything. (Python reserves the right to not 
actually make a copy in cases where it actually doesn't matter.)

There are a couple of shortcuts for this:

# copy a dictionary
new = old.copy()

# copy a list, or tuple
new = old[:]  # make a slice from the start to the end


-- 
Steven

From steve at pearwood.info  Sat Jan  4 06:46:56 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 4 Jan 2014 16:46:56 +1100
Subject: [Tutor] What's in a name?
In-Reply-To: <20140104045919.GR29356@ando>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <20140104045919.GR29356@ando>
Message-ID: <20140104054656.GU29356@ando>

On Sat, Jan 04, 2014 at 03:59:19PM +1100, Steven D'Aprano wrote:

> - eval is dangerous. The number one cause of software vulnerabilities 
>   (i.e. bugs which can be used by viruses and malware) today is code 
>   ejection, which is a fancy way of saying "somebody screwed up with
>   eval or the equivalent".

Sigh. It's spelled code *injection*.


-- 
Steven

From breamoreboy at yahoo.co.uk  Sat Jan  4 06:50:35 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sat, 04 Jan 2014 05:50:35 +0000
Subject: [Tutor] Copying [was Re:  What's in a name?]
In-Reply-To: <20140104054459.GT29356@ando>
References: <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <CAGZAPF4WG2pKvkQuHCzgokWvQO5JFaf3x53GEmEwsB-vkPqLFQ@mail.gmail.com>
 <CAGZAPF7KFKDGCTempB+Q74E9g=TLt2FS7ADwtBWuOS36BDW_0w@mail.gmail.com>
 <CAO5ffbZY4JbzS0ygbOtUm8MsmCWeRW_z-NOoxQ=Q6eCAGr0hzQ@mail.gmail.com>
 <20140104054459.GT29356@ando>
Message-ID: <la87dv$2no$1@ger.gmane.org>

On 04/01/2014 05:44, Steven D'Aprano wrote:
> On Fri, Jan 03, 2014 at 01:53:42PM -0500, Keith Winston wrote:
>
>> That's what I meant to do: make a copy when I wrote chute_nums = chutes. So
>> I should have passed chute_nums to summarize_game, but it still wouldn't
>> work (because it's not a copy).
>
> Python never makes a copy of objects when you pass them to a function or
> assign them to a name. If you want a copy, you have to copy them
> yourself:
>
> import copy
>
> acopy = copy.copy(something)
>
>
> ought to work for just about anything. (Python reserves the right to not
> actually make a copy in cases where it actually doesn't matter.)
>
> There are a couple of shortcuts for this:
>
> # copy a dictionary
> new = old.copy()
>
> # copy a list, or tuple
> new = old[:]  # make a slice from the start to the end
>
>

Please be aware of the difference between deep and shallow copies see 
http://docs.python.org/3/library/copy.html

-- 
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 Jan  4 06:56:00 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 4 Jan 2014 16:56:00 +1100
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbYrLKjzPTOCRg=O7btHd9bSEm2KxJ5ODm48L7X+1-2OPw@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <20140104045919.GR29356@ando>
 <CAO5ffbYrLKjzPTOCRg=O7btHd9bSEm2KxJ5ODm48L7X+1-2OPw@mail.gmail.com>
Message-ID: <20140104055600.GV29356@ando>

On Sat, Jan 04, 2014 at 12:32:19AM -0500, Keith Winston wrote:
> On Fri, Jan 3, 2014 at 11:59 PM, Steven D'Aprano <steve at pearwood.info>wrote:
> 
> > thelist = vars()[name]
>
> 
> I see: vars() certainly looks less dangerous than eval(), but I'm guessing
> that's still smelly code? I hadn't known about vars() or I probably would
> have used it.

Yes, it's still a bit smelly: but only a bit, since while "direct" code 
is the idea, sometimes the only way to do things is with one (or two) 
layers of indirection.

Code should (as a general rule) not rely on, or be affected by, the name 
of the variable. Functions which inspect the running environment (i.e. 
peek deep inside the interpreter) or use eval or other techniques to 
operate "behind the scenes" on *names* rather than values can often lead 
to confusing code. As debugging tools, they're useful. Putting such 
functionality inside normal everyday programs is a code smell.


-- 
Steven

From keithwins at gmail.com  Sat Jan  4 07:24:40 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 4 Jan 2014 01:24:40 -0500
Subject: [Tutor] Copying [was Re: What's in a name?]
In-Reply-To: <la87dv$2no$1@ger.gmane.org>
References: <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <CAGZAPF4WG2pKvkQuHCzgokWvQO5JFaf3x53GEmEwsB-vkPqLFQ@mail.gmail.com>
 <CAGZAPF7KFKDGCTempB+Q74E9g=TLt2FS7ADwtBWuOS36BDW_0w@mail.gmail.com>
 <CAO5ffbZY4JbzS0ygbOtUm8MsmCWeRW_z-NOoxQ=Q6eCAGr0hzQ@mail.gmail.com>
 <20140104054459.GT29356@ando> <la87dv$2no$1@ger.gmane.org>
Message-ID: <CAO5ffbaLDpxbcC871QEWBZ-2jYq2mk5cZFeyjviRNOzmf19OJg@mail.gmail.com>

Thanks for all this. I ended up using

newdict = dict(olddict), which seemed to work fine. I hadn't heard about
the copy module until now. I had heard about deep/shallow copies, though in
this particular example (all int dicts), I don't think there's a
difference...?


On Sat, Jan 4, 2014 at 12:50 AM, Mark Lawrence <breamoreboy at yahoo.co.uk>wrote:

> On 04/01/2014 05:44, Steven D'Aprano wrote:
>
>> On Fri, Jan 03, 2014 at 01:53:42PM -0500, Keith Winston wrote:
>>
>>  That's what I meant to do: make a copy when I wrote chute_nums = chutes.
>>> So
>>> I should have passed chute_nums to summarize_game, but it still wouldn't
>>> work (because it's not a copy).
>>>
>>
>> Python never makes a copy of objects when you pass them to a function or
>> assign them to a name. If you want a copy, you have to copy them
>> yourself:
>>
>> import copy
>>
>> acopy = copy.copy(something)
>>
>>
>> ought to work for just about anything. (Python reserves the right to not
>> actually make a copy in cases where it actually doesn't matter.)
>>
>> There are a couple of shortcuts for this:
>>
>> # copy a dictionary
>> new = old.copy()
>>
>> # copy a list, or tuple
>> new = old[:]  # make a slice from the start to the end
>>
>>
>>
> Please be aware of the difference between deep and shallow copies see
> http://docs.python.org/3/library/copy.html
>
> --
> My fellow Pythonistas, ask not what our language can do for you, ask what
> you can do for our language.
>
> Mark Lawrence
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140104/d3bdea17/attachment-0001.html>

From steve at pearwood.info  Sat Jan  4 10:14:23 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 4 Jan 2014 20:14:23 +1100
Subject: [Tutor] python, speed, game programming
In-Reply-To: <CABicbJ+4X7NkNwZBBjn0yaEgiaJ2opVyReNYspAeOs28joC+jg@mail.gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
 <CABicbJ+4X7NkNwZBBjn0yaEgiaJ2opVyReNYspAeOs28joC+jg@mail.gmail.com>
Message-ID: <20140104091423.GW29356@ando>

On Fri, Jan 03, 2014 at 02:11:21PM -0800, Devin Jeanpierre wrote:
> On Fri, Jan 3, 2014 at 1:53 PM, Keith Winston <keithwins at gmail.com> wrote:
> > I am gearing up for the next project (yeah, an eventual end to Chutes &
> > Ladders!). It is a typing tutor, I am inclined to use it to learn Dvorak but
> > I would expect it easily adapted to QWERTY or anything else.
[...]
> Modern computers are just so absurdly fast that the overhead Python
> has compared to other languages just doesn't matter for the kind of
> work you are doing. If you typed at a hundred characters per second
> Python could still keep up, unless there's something about your
> problem you aren't describing.

While I agree with Devin, it is possible to write absurdly slow code in 
*any* language. This is why is is better to write straightforward, 
simple code in preference to complicated, intricate code -- it is easier 
to understand simple code, which means it is easier to work out which 
bits are bottlenecks and do something about them. Then, only if it turns 
out the code is too slow, do you add complexity to speed it up.


-- 
Steven

From alan.gauld at btinternet.com  Sat Jan  4 10:27:56 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 04 Jan 2014 09:27:56 +0000
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
Message-ID: <la8k6h$imt$1@ger.gmane.org>

On 04/01/14 04:47, Keith Winston wrote:
> Here is what I think will be about the final version of C and L.

Much better. Only one suggestion...

> def run_CandL(gamecount):
>      tarray = CandL_Array()
>      tarray.populate(gamecount)
>      tarray.print_stuff()

Remove the middle line by making the array take a gamecount
argument and call populate from the init method. Why should the user 
have to populate the class when it can do it itself?

Being picky I'm not keen on "stuff" as part of the name of
the final method call. Surely there a slkightly descriptive term 
somewhere? print_stats, print_data, print_game_results etc?


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From denis.spir at gmail.com  Sat Jan  4 11:07:25 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 04 Jan 2014 11:07:25 +0100
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
Message-ID: <52C7DD5D.6000700@gmail.com>

On 01/04/2014 05:47 AM, Keith Winston wrote:
> Here is what I think will be about the final version of C and L. I
> rearranged it quite a bit (into 2 classes), fixed a bug or two, and
> generally cleaned it up a bit. I haven't really polished it, but hopefully
> it will be less difficult to read... which is to say, if anyone wants to go
> through it AGAIN (at your leisure) I would appreciate comments on style,
> etc.

A few notes:

* You don't need, for lists, names likes 'self.chutes_list': 'self.chutes' does 
the job and is de facto standard in Python. Similarly, for a dict like one 
mapping names to phones, one can use 'names_phones' (read: "names' phones" or 
"names to phones").

* Try to find a satisfying personal convention (there is no standard in Python) 
for indexes (number of A thing) and counts (numbers of things), which constantly 
come up programming. (I use i_thing & n_things, or just i & n when in context 
there is no possible ambiguity.)

* What is the point of method reset apart from __init__? (Even if you need to 
reset a game after it has started, you could call __init__ for that. Rarely 
needed, but happens, esp. in games when eg a trap or bad luck brings the player 
back to start.)

* Make a class for results (see example below). Not only it is semantically 
correct (a result is a composite object, not a collection, but youy use a list), 
not only it makes code cleaner, but it allows more simply modifying and 
extending. Also, you could add there, directly in the concerned class, methods 
that deal with results (in addition to ones for result output, as in the 
example, which I also write first).

* When posting code, place your signature (-- Keith) _after_. Else, it causes 
weird bugs in email readers (eg mine, Thunderbird); I cannot even copy-paste it, 
for some weird reason.

Denis

=== class Result example ==============================

class Result:
     ''' result of an individual game

     Fields:
     * no        : 'num?ro' (?) of the game
     * n_moves   : number of moves
     * chutes    : list of chute positions
     * ladders   : list of ladder positions

     Methods:
     * __repr__  : notation, as in code
     * __str__   : writing with field names
     '''
     def __init__ (self, no, n_moves, chutes, ladders):
         ''' Store game stat data. '''
         self.no         = no
         self.n_moves    = n_moves
         self.chutes     = chutes
         self.ladders    = ladders

     # output
     def __repr__ (self):
         ''' notation, as in code (for programme feedback) '''
         return "Result(%r, %r, %r, %r)" % \
             (self.no, self.n_moves, self.chutes, self.ladders)
     def __str__ (self):
         ''' writing with field names (eg for user info in UI) '''
         return "{no:%s  n-moves:%s  chutes:%s  ladders:%s}" % \
             (self.no, self.n_moves, self.chutes, self.ladders)

# fake example
res = Result(3, 333, [1,2,3], [99,33,11])
print("\n%r\n\n%s\n" %(res, res))

""" writes out:

Result(3, 333, [1, 2, 3], [99, 33, 11])

{no:3  n-moves:333  chutes:[1, 2, 3]  ladders:[99, 33, 11]}

"""

From denis.spir at gmail.com  Sat Jan  4 11:11:36 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 04 Jan 2014 11:11:36 +0100
Subject: [Tutor] simple arg problem
In-Reply-To: <20140104044532.GQ29356@ando>
References: <CAO5ffbbHkob+jw+hRh9YozCVkxXhjTpnJTNhqnKOCd7qS6HHjQ@mail.gmail.com>
 <CAO5ffbbSs150eE-o-rLokG4Y090OfLSd-0YRtZ3F30mwRU80GQ@mail.gmail.com>
 <20140104044532.GQ29356@ando>
Message-ID: <52C7DE58.1090307@gmail.com>

On 01/04/2014 05:45 AM, Steven D'Aprano wrote:
> On Fri, Jan 03, 2014 at 09:56:25PM -0500, Keith Winston wrote:
>> gmail is driving me crazy. Anyway, every time I run it with:
>>
>> if __name__ == "__main__":
>>      tarray = CandL_Array
>>      tarray.populate(100)
>>
>> I get an error
>>
>> Traceback (most recent call last):
>>    File "/home/keithwins/Dropbox/Python/CandL8.py", line 127, in <module>
>>      tarray.populate(100)
>> TypeError: populate() missing 1 required positional argument: 'gamecount1'
>>>>>
>
> Eryksun has already solved your immediate problem, but I'd like to point
> out that the above has a couple of code smells.
>
> Are you familiar with the concept of a code smell? Code which smells
> wrong might not be wrong, but it's worth giving it a good hard long look
> just to be sure. Like Grandma used to say about your nappies, "If it
> stinks, change it", code smells usually suggest there's a problem with
> the code.
>
> http://www.codinghorror.com/blog/2006/05/code-smells.html
>
> Like parmesan and blue cheeses, or durian fruit, there are a few
> exceptions, but normally code is like food: it only smells bad when it
> has gone off. You should never write smelly code without giving it a
> good, hard look.
>
> Anyway, back to your code... you have a class CandL_Array which
> apparently you call with no arguments. If it needed arguments, you
> wouldn't have made the error you did, which is to forget to include
> parentheses:
>
> # No
> tarray = CandL_Array  # makes tarray an alias to the class
>
> # Yes
> tarray = CandL_Array()  # makes tarray an instance of the class
>
>
> If CandL_Array() needed arguments, you wouldn't have forgotten the round
> brackets, and wouldn't have got the error you did. So there's a little
> whiff of a smell right there... why does the class not take any
> arguments? That suggests that every instance it creates is exactly the
> same as every other instance. That's not necessarily wrong, but it is a
> little bit whiffy.
>
> But then there's the next line:
>
> tarray.populate(100)
>
> Apparently, and I'm reading between the lines here, once you create the
> CandL_Array instance, you can't use it until you populate it. If I'm
> right, that's pretty smelly. That means you have errors like this:
>
> tarray = CandL_Array()  # Initialise an instance.
> tarray.play_game()  # or something, you don't show that part of the code
>
>
> which blows up in your face because you forgot to call populate first.
> That's ugly, stinking code. Imagine if you had to write code like this:
>
> x = float("12.345")
> x.prepare()  # Make the float ready to use
> y = x + 1.0  # Now we can use it!
>
> Yuck.
>
> Most of the time, creating an instance should do everything needed to
> prepare it for use. I suspect that your game is no exception. If you
> need to call some method to make the instance ready to use, then the
> constructor __new__ or initialiser __init__ should do so.
>
> You don't even have to get rid of the populate method. You just need
> to change this:
>
> class CandL_Array:
>      def __init__(self):
>          ...
>      def populate(self, size):
>          ...
>
>
> to this:
>
> class CandL_Array:
>      def __init__(self, size):
>          ...
>          self.populate(size)
>      def populate(self, size):
>          ...
>
>
> and change this:
>
> tarray = CandL_Array()
> tarray.populate(100)
>
>
> to this:
>
> tarray = CandL_Array(100)

Waow! that was problem analysis.

Denis


From blechnum at fireflyuk.net  Sat Jan  4 11:47:15 2014
From: blechnum at fireflyuk.net (blechnum at fireflyuk.net)
Date: Sat, 04 Jan 2014 10:47:15 +0000
Subject: [Tutor] python problems on android
Message-ID: <52c7e6b3.1e04.1eb8.52fc@fireflyuk.net>




Ok. Will try and explain the problem.
I wrote a script in python and found I could use it on my android 
phone with SL4a.
It was really useful.
Haven't used it for a few months.
A few days ago I decided to improve it and found it no longer works.
the problem seems to be that when it reaches an input statement it 
will only accept a number.
If I try to input a letter I get an error message the same as if I had 
just typed the letter into the command line.
I am not sure what has happened, it used to work ok.

Is there another way of getting input into my script without 
using.....input?

Or better still does anyone understand what is going wrong?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140104/d3014938/attachment.html>

From denis.spir at gmail.com  Sat Jan  4 11:51:37 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 04 Jan 2014 11:51:37 +0100
Subject: [Tutor] What's in a name?
In-Reply-To: <CAO5ffbYrLKjzPTOCRg=O7btHd9bSEm2KxJ5ODm48L7X+1-2OPw@mail.gmail.com>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <20140104045919.GR29356@ando>
 <CAO5ffbYrLKjzPTOCRg=O7btHd9bSEm2KxJ5ODm48L7X+1-2OPw@mail.gmail.com>
Message-ID: <52C7E7B9.3080606@gmail.com>

On 01/04/2014 06:32 AM, Keith Winston wrote:
> On Fri, Jan 3, 2014 at 11:59 PM, Steven D'Aprano <steve at pearwood.info>wrote:
>
>> thelist = vars()[name]
>
>
>
> I see: vars() certainly looks less dangerous than eval(), but I'm guessing
> that's still smelly code? I hadn't known about vars() or I probably would
> have used it.

It is not as much smelly as somewhat "meta". It talks about Python's own 
conception, here about scopes (or namespaces). [I will let so-called 
"non-locals" aside, for simplicity.] Imagine that Python provided 2 dicts, 
always there:
* top_vars, for vars defined at top module level (included imports)
* local_vars for function local vars (included inputs)
Then, you could write:

a = 1
def f ():
     top_vars.a   = 2	# redef / change symbol a
     local_vars.b = 1	# def / create symbol b
     print(top_vars.a, local_vars.b)

which is the same as actual Python code:

a = 1
def f ():
     global a
     a = 2
     b = 1
     print(a, b)

but shows more or less how things work behind the stage.

local() and globals() return a dict equivalent to my imaginary local_vars and 
global_vars, resp. [But in the actual implementation, things are somewhat more 
low-level for efficiency; esp. IIRC locals are not truely named if you don't ask 
for them, as in most dynamic langs; but I may be wrong]. If Python scope were 
simply, truely, directly Python data (dicts), without the need to call a 
function that fabricates the dict on need, then the language would be 
"homoiconic" (on this aspect of its functioning), which just means that it works 
using its own data (types). Thus, the "meta" view.

vars() is somewhat special, works for any namespace-like component. See:
http://docs.python.org/3/library/functions.html
for a few details.

Denis



From keithwins at gmail.com  Sat Jan  4 11:54:51 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 4 Jan 2014 05:54:51 -0500
Subject: [Tutor] What's in a name?
In-Reply-To: <20140104055600.GV29356@ando>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <20140104045919.GR29356@ando>
 <CAO5ffbYrLKjzPTOCRg=O7btHd9bSEm2KxJ5ODm48L7X+1-2OPw@mail.gmail.com>
 <20140104055600.GV29356@ando>
Message-ID: <CAO5ffbY15DMP4SL4G+S8chrMnsOdj8WPoYQUDDgnio2LHNp5dw@mail.gmail.com>

Thanks to both of you. In this particular case, the main use of eval() was
only for 2 calls, which were essentially hard-coded (you could see the
calls to summarize_game in my code). I was looking for a more general
solution to what I was trying to do, but I don't need it for this project.
Still, this has been an informative conversation.


On Sat, Jan 4, 2014 at 12:56 AM, Steven D'Aprano <steve at pearwood.info>wrote:

> On Sat, Jan 04, 2014 at 12:32:19AM -0500, Keith Winston wrote:
> > On Fri, Jan 3, 2014 at 11:59 PM, Steven D'Aprano <steve at pearwood.info
> >wrote:
> >
> > > thelist = vars()[name]
> >
> >
> > I see: vars() certainly looks less dangerous than eval(), but I'm
> guessing
> > that's still smelly code? I hadn't known about vars() or I probably would
> > have used it.
>
> Yes, it's still a bit smelly: but only a bit, since while "direct" code
> is the idea, sometimes the only way to do things is with one (or two)
> layers of indirection.
>
> Code should (as a general rule) not rely on, or be affected by, the name
> of the variable. Functions which inspect the running environment (i.e.
> peek deep inside the interpreter) or use eval or other techniques to
> operate "behind the scenes" on *names* rather than values can often lead
> to confusing code. As debugging tools, they're useful. Putting such
> functionality inside normal everyday programs is a code smell.
>
>
> --
> Steven
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140104/7ef448c9/attachment.html>

From keithwins at gmail.com  Sat Jan  4 11:56:30 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 4 Jan 2014 05:56:30 -0500
Subject: [Tutor] python problems on android
In-Reply-To: <52c7e6b3.1e04.1eb8.52fc@fireflyuk.net>
References: <52c7e6b3.1e04.1eb8.52fc@fireflyuk.net>
Message-ID: <CAO5ffbbbMLCs2kz_iS5yp31Wxsw7-nLOUcqHpX2ydBSzMpTGVQ@mail.gmail.com>

Perhaps you could include the script?


On Sat, Jan 4, 2014 at 5:47 AM, <blechnum at fireflyuk.net> wrote:

>
>
> Ok. Will try and explain the problem.
> I wrote a script in python and found I could use it on my android phone
> with SL4a.
> It was really useful.
> Haven't used it for a few months.
> A few days ago I decided to improve it and found it no longer works.
> the problem seems to be that when it reaches an input statement it will
> only accept a number.
> If I try to input a letter I get an error message the same as if I had
> just typed the letter into the command line.
> I am not sure what has happened, it used to work ok.
>
> Is there another way of getting input into my script without
> using.....input?
>
> Or better still does anyone understand what is going wrong?
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>


-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140104/77157872/attachment.html>

From denis.spir at gmail.com  Sat Jan  4 12:05:18 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 04 Jan 2014 12:05:18 +0100
Subject: [Tutor] Fwd: What's in a name?
In-Reply-To: <20140104053657.GS29356@ando>
References: <CAO5ffbZQ+h1660UpdLfBGiAW6_LoPmt3ip1aKBC-KsgdNq04Ew@mail.gmail.com>
 <CAO5ffbYWYN2NTBBS4uEzp5v=Az-zfW-_REmFQQp_QZBMiUsQQQ@mail.gmail.com>
 <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <la5ll3$tkt$1@ger.gmane.org>
 <CAO5ffbaAAc35c3ps-WmauXKhJ4HRzf87mW-hVJ1k09UT_Tfm6Q@mail.gmail.com>
 <20140104053657.GS29356@ando>
Message-ID: <52C7EAEE.4040603@gmail.com>

On 01/04/2014 06:36 AM, Steven D'Aprano wrote:
> Now, it's true that when *debugging code*, being able to see the name of
> the variable and the contents of the variable is useful. But in ordinary
> code, why would you care to print the name of the variable and its
> contents. Who cares what the variable is named?
>
> Debuggers stick all sorts of nasty hooks into the running interpreter in
> order to do this (and much more), and we should all be thankful that (1)
> debuggers exist, (2) that they aren't running by default, and most
> importantly (3) that we don't have to write code like them.
>
> In addition to powerful debuggers, we also have fantastic poor-man's
> debugger called "print":
>
> for name, value in zip(
>              'alist blist clist'.split(), [alist, blist, clist]):
>      print(name, "=", value)

I dream of a 'note' debug write function (or better statement with keyword, like 
assert) working like:

	n = 0
	i = 1
         note n 		# ==> n = 1
         note i n	# ==> i = 0 | n = 1
	note i (type)	# ==> i = 0 (int)
	note i (where)	# ==> i = 0 (mod.cls.f, 333)

(The latter version gives full func name & line n? in module.)

I have always disliked debuggers, and REPL's as well (both too rigid & heavy), 
so maybe my view is somewhat marginal.

> Yes, it's a little bit messy code. We have to repeat the name of the
> variable twice. But this isn't code that will hang around in the
> finished program. It only need exist for just long enough to debug the
> problem we're having (you are having a problem, I presume?), then, it's
> job done, it's gone.

You are right, but people who like exploratory, flexible, trial-and-error 
programming (even at tmes, not systematically), constantly write such debug 
statemetns or pieces of code, anew. (That's why I tend to let them code for a 
while; and I use a "write" debug func which just wraps print, just to have 
another name and be able to find & erase them all at once quickly.)

Denis

From denis.spir at gmail.com  Sat Jan  4 12:10:49 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 04 Jan 2014 12:10:49 +0100
Subject: [Tutor] Copying [was Re: What's in a name?]
In-Reply-To: <CAO5ffbaLDpxbcC871QEWBZ-2jYq2mk5cZFeyjviRNOzmf19OJg@mail.gmail.com>
References: <la5j3p$76k$1@ger.gmane.org>
 <CAO5ffbZFToacn29UG1MsQ+qtf15ub+Xsgp4Nw0HcziHy0xrn8g@mail.gmail.com>
 <CAO5ffbZ-H38JFHp-gz1nEVG+5REPdZxq7RH0Xqt96xpNARqj=w@mail.gmail.com>
 <CAO5ffbZ-KO_2Jf3AzTStGhyhCvq93M8cORz81CeHhWS+QoiUVA@mail.gmail.com>
 <CAGZAPF6c0jAex697bms4etcT7FN=-m5DJONShL6vNGNBrjtP5A@mail.gmail.com>
 <CAO5ffbYM76jFZZLQ3EjVS+Ab+cxNkfn4QuSdakZK=qO4XJ4tPw@mail.gmail.com>
 <CAO5ffbarmsWEgPxZQu4aQQ0YTu5CJA5mPsMPVT53cvmJU6s_Gg@mail.gmail.com>
 <CAGZAPF4WG2pKvkQuHCzgokWvQO5JFaf3x53GEmEwsB-vkPqLFQ@mail.gmail.com>
 <CAGZAPF7KFKDGCTempB+Q74E9g=TLt2FS7ADwtBWuOS36BDW_0w@mail.gmail.com>
 <CAO5ffbZY4JbzS0ygbOtUm8MsmCWeRW_z-NOoxQ=Q6eCAGr0hzQ@mail.gmail.com>
 <20140104054459.GT29356@ando> <la87dv$2no$1@ger.gmane.org>
 <CAO5ffbaLDpxbcC871QEWBZ-2jYq2mk5cZFeyjviRNOzmf19OJg@mail.gmail.com>
Message-ID: <52C7EC39.2050302@gmail.com>

On 01/04/2014 07:24 AM, Keith Winston wrote:
> I had heard about deep/shallow copies, though in
> this particular example (all int dicts), I don't think there's a
> difference...?

There's none, you're right. It's only whenever inner items (fields, etc...) 
themselves are complex elements and mutable. Else, mutations on original items 
would show on copies, and conversely. But when htere are simple items only, or 
immutable (tuples, strings...) the ambiguity does not exist.

Denis

From blechnum at fireflyuk.net  Sat Jan  4 12:24:59 2014
From: blechnum at fireflyuk.net (blechnum at fireflyuk.net)
Date: Sat, 04 Jan 2014 11:24:59 +0000
Subject: [Tutor] python problems on android
Message-ID: <52c7ef8b.1e04.147c.65af@fireflyuk.net>


I havent included the script as it seems to be the use ' input'  on my 
phone that now wont work.

At the command line (on my computer)  I can type

h = input(" enter character ")

and when i type a response and enter it, then type h and return, i am 
given back the response i put in.

I type j , get 'j' back

Now on my phone i can do the same.

And here is the odd bit
If I type a number in, the response will be the number

type 4, get '4' back

but if i  type in a letter I get an error, the same error as if i had 
typed in the response to the command line.

NameError: name '<response to input request>" is not defined

so if my response was G

I get back NameError: name 'G" is not defined


Is there any other (easy) way I can get around this by not using input 
for input?
could I use android to pass input to my script?



From denis.spir at gmail.com  Sat Jan  4 12:19:53 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 04 Jan 2014 12:19:53 +0100
Subject: [Tutor] python, speed, game programming
In-Reply-To: <20140104091423.GW29356@ando>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
 <CABicbJ+4X7NkNwZBBjn0yaEgiaJ2opVyReNYspAeOs28joC+jg@mail.gmail.com>
 <20140104091423.GW29356@ando>
Message-ID: <52C7EE59.7010301@gmail.com>

On 01/04/2014 10:14 AM, Steven D'Aprano wrote:
> While I agree with Devin, it is possible to write absurdly slow code in
> *any* language. This is why is is better to write straightforward,
> simple code in preference to complicated, intricate code -- it is easier
> to understand simple code, which means it is easier to work out which
> bits are bottlenecks and do something about them. Then, only if it turns
> out the code is too slow, do you add complexity to speed it up.

+++

I would add: it is preferable to write _clear_ code, in the widest sense of 
"easy to understand". Simplicity is not the only factor or clarity (good naming, 
using right constructs [1], direct mapping from conception to code structure & 
logic...); also, some simple schemes are very difficult to figure out (eg 
various functional programing idioms).

 From clear code, everything else is easier: modification, extension, improving 
efficeincy (time and/or space), doc, debugging, testing, trials... I would even 
say (surprisingly?) that clarity has precedence over correctness: it's easier to 
correct clear code, while correct but obscure code makes anything else harder.

personal point of view: Issue number 1 in programming is understanding (what 
code actually means and actually does). That's why we spend about 97.531% of our 
time thinking ;-)

Denis

[1] Python's "one good way to do it".

From denis.spir at gmail.com  Sat Jan  4 12:31:33 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 04 Jan 2014 12:31:33 +0100
Subject: [Tutor] python, speed, game programming
In-Reply-To: <CAO5ffbZKBUWmaQmDcA7QeHmpRLKpezOdP995tjtiYpR=wDJiVA@mail.gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
 <la7neq$mbl$1@ger.gmane.org>
 <CAO5ffbZKBUWmaQmDcA7QeHmpRLKpezOdP995tjtiYpR=wDJiVA@mail.gmail.com>
Message-ID: <52C7F115.9010200@gmail.com>

On 01/04/2014 02:38 AM, Keith Winston wrote:
> The thing that put me on edge was noticing that my simple
> Chutes & Ladders game doesn't go ANY faster on a machine that benchmarks
> perhaps 1000 times faster than another...

You could say this about most programs in most langs. Actually, some even 
regress in perf while harware progresses by orders of magnitude. This is due to 
the whole software platform (OS + layers of UI and graphics, plus underlying 
libs and frameworks, plus the ones your apps explicitely call) becoming more and 
more HW resource consuming, this independently of actual app logic processing.

As Alan evoked, I remember how early PCs were fast, retrospectively, with 
comparatively ridiculous HW resources (clock freq & live mem mainly). Resource 
consumptions of what I call here software platforms have progressed at a rythm 
comparable to HW resources. However, in general, there remain resource gains for 
apps, in absolute (rather than proportional) value. (But you can see that prop 
gains are not that important when running multiple heavy apps at once.)

Denis

From keithwins at gmail.com  Sat Jan  4 12:33:59 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 4 Jan 2014 06:33:59 -0500
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <52C7DD5D.6000700@gmail.com>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
 <52C7DD5D.6000700@gmail.com>
Message-ID: <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>

Thanks Alan & Denis: Alan, the improvement you suggested had already been
made, and adopted. Good catch.

Denis: alas, there are chutes and ladders dicts, but I guess your chutes &
ladders lists are local to the results class... Your suggestion is quite
shocking to me, I wouldn't have thought of creating a class for results...
I guess it allows clearer modularity of the final candl_array? I don't
really get it... I think you are using it, essentially, for nothing other
than a data structure, right? And some cleaner print options, though I have
only looked at the raw game data for debugging... it's a great suggestion,
obviously, because I am a little dumbfounded by it, and it's making me
think.

My initial reaction is concern about having too many classes, but I don't
really have any sense of how important that is. I was playing with storing
ChutesAndLadders instances in my game array, but of course they include all
their methods, etc: all kinds of overhead (at least, that's my impression),
which is why I created the results method, so I could just pass a... list?
composite object? Collection? I can't really sort out what the latter two
mean in Python, and must be looking in the wrong place... while I was
researching I found out about namedtuple(), which seems like a promising
structure for game data, but I haven't really looked into it. It might also
be a collection...

The entire game is to be played in bulk (that is, it's really a statistical
foray, albeit a silly one), so the candl_array might get large (perhaps
millions of "records" -- results lists). Is there some way the Results
class helps that?

keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140104/281bbab2/attachment-0001.html>

From keithwins at gmail.com  Sat Jan  4 12:46:53 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 4 Jan 2014 06:46:53 -0500
Subject: [Tutor] python problems on android
In-Reply-To: <52c7ef8b.1e04.147c.65af@fireflyuk.net>
References: <52c7ef8b.1e04.147c.65af@fireflyuk.net>
Message-ID: <CAO5ffbburgjC=4=NLADEpNUE7ALmw5rOz4uq+SJ2MOdA2KCNTA@mail.gmail.com>

Well, I probably can't help you, I haven't installed SL4 (yet), and am a
Python beginner myself anyway. I imagine others might be more prepared to
help you with a copy of the script.

However: something about the way you are responding to this thread keeps
breaking it, so you end up starting a new thread (you've started three).
That's a little hard to keep track of, and there are those here who truly
hate that kind of thing. This message, for example, started a new thread
(at least for me, I assume others), but your last reply didn't, so if you
know what you did (or didn't do) that time, do that from now on!

My only thought on the problem is: what is the script doing with the input?
Maybe for some reason a number works in that context, but a letter doesn't?
Even just including a few lines of the code around the input statement
might be better than nothing.

keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140104/0451a31a/attachment.html>

From denis.spir at gmail.com  Sat Jan  4 12:50:21 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 04 Jan 2014 12:50:21 +0100
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>	<52C7DD5D.6000700@gmail.com>
 <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>
Message-ID: <52C7F57D.4060600@gmail.com>

On 01/04/2014 12:33 PM, Keith Winston wrote:
> Thanks Alan & Denis: Alan, the improvement you suggested had already been
> made, and adopted. Good catch.
>
> Denis: alas, there are chutes and ladders dicts, but I guess your chutes &
> ladders lists are local to the results class... Your suggestion is quite
> shocking to me, I wouldn't have thought of creating a class for results...
> I guess it allows clearer modularity of the final candl_array? I don't
> really get it... I think you are using it, essentially, for nothing other
> than a data structure, right? And some cleaner print options, though I have
> only looked at the raw game data for debugging... it's a great suggestion,
> obviously, because I am a little dumbfounded by it, and it's making me
> think.
>
> My initial reaction is concern about having too many classes, but I don't
> really have any sense of how important that is. I was playing with storing
> ChutesAndLadders instances in my game array, but of course they include all
> their methods, etc: all kinds of overhead (at least, that's my impression),
> which is why I created the results method, so I could just pass a... list?
> composite object? Collection? I can't really sort out what the latter two
> mean in Python, and must be looking in the wrong place... while I was
> researching I found out about namedtuple(), which seems like a promising
> structure for game data, but I haven't really looked into it. It might also
> be a collection...
>
> The entire game is to be played in bulk (that is, it's really a statistical
> foray, albeit a silly one), so the candl_array might get large (perhaps
> millions of "records" -- results lists). Is there some way the Results
> class helps that?

A class for results makes your global game result stats a plain list of result 
object, each with a clear composition / structure, with nicely self-commenting 
field names. What best could you dream of. A result is "by nature" (if I may 
say) a composite with well definite fields; think at a C struct.

Some may have different views, but I'd say it's worth making a class (custom 
object type) when:
* it defines conceptually and practically _composite_ elements, just like C 
structs or Pascal records,
* or, some type-specific methods are needed or useful.
(in fact string output methods are nearly always useful, for signicant elements 
or element types of an app, if only for your own feedback as programmer, in 
debugging, testing, diagnosing...)

An additional factor is, as in your case, that there are multiple such elements 
[*]. Usually, they are then stored in a collection (list, set, dict).

Denis

[*] Unfortunately, in python there are no individual composite objects: Python 
provides "class-based" OOP (as opposed to "prototype-based", or object-based if 
you like). In eg Lua or JS, you'd just write for instance:
	origin = {x=0, y=0, label="Origin"}
full dot. (And then access fields like 'origin.y', like in python for class 
instances.)
One can simulate that in python, or abuse dicts (however with annoying syntax), 
but in any  case it is not a feature of the language.


From chigga101 at gmail.com  Sat Jan  4 12:49:27 2014
From: chigga101 at gmail.com (Matthew Ngaha)
Date: Sat, 4 Jan 2014 11:49:27 +0000
Subject: [Tutor] python problems on android
In-Reply-To: <52c7ef8b.1e04.147c.65af@fireflyuk.net>
References: <52c7ef8b.1e04.147c.65af@fireflyuk.net>
Message-ID: <CACzNyA0ELm_+8eA6+GCaYOfucE0hTT13zxMPXt882wm7R7wPBw@mail.gmail.com>

On Sat, Jan 4, 2014 at 11:24 AM,  <blechnum at fireflyuk.net> wrote:
>
> I havent included the script as it seems to be the use ' input'  on my phone
> that now wont work.
>

Even if the error is with 'input', it is still an odd error and no one
will be able to debug your program or have a clue what's going wrong
if you don't provide us any code. It will save a lot of time also.

From blechnum at fireflyuk.net  Sat Jan  4 13:16:29 2014
From: blechnum at fireflyuk.net (blechnum at fireflyuk.net)
Date: Sat, 04 Jan 2014 12:16:29 +0000
Subject: [Tutor] python problems on android
Message-ID: <52c7fb9d.1e04.18d0.4920@fireflyuk.net>


Thank you. I see, it was running python 3.x

 when that  didn't work I uninstalled it

 and used SL4a to reinstall

it installed Python 2.x

(Thanks, sorry for being slow to catch on and for multiple threads)

So raw_input should work instead of input



From steve at pearwood.info  Sat Jan  4 13:15:18 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 4 Jan 2014 23:15:18 +1100
Subject: [Tutor] python, speed, game programming
In-Reply-To: <CAO5ffbZKBUWmaQmDcA7QeHmpRLKpezOdP995tjtiYpR=wDJiVA@mail.gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
 <la7neq$mbl$1@ger.gmane.org>
 <CAO5ffbZKBUWmaQmDcA7QeHmpRLKpezOdP995tjtiYpR=wDJiVA@mail.gmail.com>
Message-ID: <20140104121516.GX29356@ando>

On Fri, Jan 03, 2014 at 08:38:47PM -0500, Keith Winston wrote:
> The thing that put me on edge was noticing that my simple
> Chutes & Ladders game doesn't go ANY faster on a machine that benchmarks
> perhaps 1000 times faster than another...

Damn! You've discovered our secret! Hidden deep insight the Python 
compiler is code that determines the speed of computer, and deliberately 
slows down the Python runtime so that it runs just as slowly on all PCs, 
no matter how fast they are or how much memory they have... 

*wink*

But seriously... This is clearly bogus. There has to be an explanation, 
apart from "Python secretly tries to run just as slow on everything". 
Even slow, inefficient code will run faster on faster hardware. But how 
much faster? How accurate are your timing measurements?

Some possible explanations:

- the method you used to time the code is inaccurate or doesn't measure 
what you think it does;

- the code you have written spends most of its time doing things that 
aren't sped up by a faster computer, e.g. waiting for human input, 
downloading data from the Internet, reading and writing to a network 
drive, etc.;

- the benchmarks that say the second computer is 1000 times faster than 
the first are bogus (not necessarily lying, although possibly lying by 
ommission).

I expect that the anwser to this mystery is a combination of the first 
and the last factors. It's harder to measure the execution speed of code 
than you might think, and most PC benchmarks are worse than you might 
think. Many benchmarks are artifical and designed as advertising, to 
show the product in the best possible light. If a machine has a CPU 
clock speed that is 1000 times faster than the last model, the 
benchmarks will all be for tiny little programlets that are reliant on 
CPU speed. Meanwhile, the fact that real-world applications see hardly 
any benefit because the computer can't push data into and out of the CPU 
any faster than before gets conveniently swept under the carpet.

(Cynical? Who, me?)


-- 
Steven

From keithwins at gmail.com  Sat Jan  4 13:19:43 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 4 Jan 2014 07:19:43 -0500
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <52C7F57D.4060600@gmail.com>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
 <52C7DD5D.6000700@gmail.com>
 <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>
 <52C7F57D.4060600@gmail.com>
Message-ID: <CAO5ffbaNu2vpjm5KKUx20KN+vpbe_fjqE4pP6g1B1fo_6tE6ow@mail.gmail.com>

Thanks again Denis, I might just have to ruminate on this, but I am
definitely having an allergic reaction.

I understand that Python doesn't have composite objects, but neither does
it dislallow my list of lists of ints and lists... which is, I imagine,
very space efficient. I think what you are in essence saying is that it's a
mistake for me to worry about space at the expense of clarity... ok, but if
I really don't need to break out those single lists ever, to speak of... it
seems like I've vastly enlarged my array for little gain.

I'm not meaning to argue, but to understand. Especially in lieu of an
upcoming project with, perhaps, larger and more complex structures. I am
increasingly curious about whether namedtuples are a good strategy for some
of this: they store their field names, as I understand it, and I can live
with an immutable type in all these cases: I wonder if they are as
efficient in named-field (key) lookup as dictionaries?

I'm also a bit confused here: obviously tuples are immutable, but one can
use lists in them... I think that makes those lists' contents immutable?
And could one define a namedtuple that included lists that were different
lengths for different instantiations (like my game results, for example)? I
really should be playing with them instead of asking questions, at this
point...

Thanks as always!

Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140104/e5c8f465/attachment-0001.html>

From breamoreboy at yahoo.co.uk  Sat Jan  4 13:53:41 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sat, 04 Jan 2014 12:53:41 +0000
Subject: [Tutor] python problems on android
In-Reply-To: <52c7e6b3.1e04.1eb8.52fc@fireflyuk.net>
References: <52c7e6b3.1e04.1eb8.52fc@fireflyuk.net>
Message-ID: <la908e$122$1@ger.gmane.org>

On 04/01/2014 10:47, blechnum at fireflyuk.net wrote:
> Ok. Will try and explain the problem.
> I wrote a script in python and found I could use it on my android phone
> with SL4a.
> It was really useful.
> Haven't used it for a few months.
> A few days ago I decided to improve it and found it no longer works.
> the problem seems to be that when it reaches an input statement it will
> only accept a number.
> If I try to input a letter I get an error message the same as if I had
> just typed the letter into the command line.
> I am not sure what has happened, it used to work ok.
> Is there another way of getting input into my script without
> using.....input?
> Or better still does anyone understand what is going wrong?
>

Both my main and spare cystal balls are at the menders so I'm terribly 
sorry but you'll have to go to all the effort of posting a sample of 
code that fails and the full traceback asssuming that there is one.

-- 
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 Jan  4 14:03:27 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 5 Jan 2014 00:03:27 +1100
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <CAO5ffbaNu2vpjm5KKUx20KN+vpbe_fjqE4pP6g1B1fo_6tE6ow@mail.gmail.com>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
 <52C7DD5D.6000700@gmail.com>
 <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>
 <52C7F57D.4060600@gmail.com>
 <CAO5ffbaNu2vpjm5KKUx20KN+vpbe_fjqE4pP6g1B1fo_6tE6ow@mail.gmail.com>
Message-ID: <20140104130324.GY29356@ando>

On Sat, Jan 04, 2014 at 07:19:43AM -0500, Keith Winston wrote:

> I understand that Python doesn't have composite objects, but neither does
> it dislallow my list of lists of ints and lists... which is, I imagine,
> very space efficient.

I'm afraid I have no idea what you mean by Python not having "composite 
objects". What's a composite object?


> I think what you are in essence saying is that it's a
> mistake for me to worry about space at the expense of clarity...

What Denis and I are trying to say is that when you are using a 
high-level language like Python, you should aim to optimize programmer 
time and effort, not computer time and effort. There are applications 
where you have to optimize what the computer does, where every byte 
counts, where microseconds matter. Python is not the right programming 
language for those applications. Python is a language for when you have 
the luxury of tens of megabytes of memory, not kilobytes, when you don't 
care whether something takes a millisecond to calculate instead of a 
tenth of a millisecond.

(Actually, there are versions of Python for embedded devices, such as 
Android, where memory does matter -- at least, where every kilobyte 
counts.)

Everything is a tradeoff. In programming, one common set of tradeoffs is 
space (memory) versus time: use more memory to run faster, or save 
memory but run slower. Python generally trades off memory for speed. 
There is very little point in trying to save bytes, because behind the 
scenes Python is using and re-using memory like its going out of 
fashion, just to ensure that it can be as fast as possible.

py> import sys
py> sys.getsizeof(42)
14

Fourteen bytes just for a tiny little integer like that??? How wasteful! 
I remember when numbers like 42 would only require *two* bytes. Of 
course, back then the biggest number you could deal with was 65535, and 
a computer with 64K of memory was considered unbelievably luxurious. 
Meanwhile, Python let's me handle numbers with thousands of digits with 
ease:

py> n = 2**10000
py> len(str(n))
3011

Another tradeoff is between programmer effort (which equals time, and 
cost) versus speed. Programs written in C are typically between 
10 and 10000 times faster than the same program written in Python, but 
they typically take between 20 and 200 times longer and more effort to 
write. You should ask, is my program *fast enough*? rather than ask if 
it is fast. Often, Python is fast enough. When it's not, there are ways 
to make it faster.

So don't sweat the small stuff. If you ever have to write an operating 
system kernel or a graphics card driver, then you need care about 
optimizing every little thing. Until then, write the most natural code 
you can, and only if it actually is too slow should you worry about it.


> I'm not meaning to argue, but to understand. Especially in lieu of an
> upcoming project with, perhaps, larger and more complex structures. I am
> increasingly curious about whether namedtuples are a good strategy for some
> of this: they store their field names, as I understand it, and I can live
> with an immutable type in all these cases: I wonder if they are as
> efficient in named-field (key) lookup as dictionaries?

Pretty close to it. Not quite, but within a factor of about 3. Let's do 
some micro-benchmarks!


First, let's create some data objects with three fields, using three 
different techniques: a dict x, a regular class with named fields y, and 
a namedtuple z.

py> x = {'a': 23, 'b': 42, 'c': 57}
py> class Record:
...     def __init__(self, a, b, c):
...             self.a = a
...             self.b = b
...             self.c = c
...
py> y = Record(23, 42, 57)
py> from collections import namedtuple
py> recordnt = namedtuple('recordnt', 'a b c')
py> z = recordnt(23, 42, 57)


Now let's set up some timing code, where we extract all three fields in 
reverse order:

py> from timeit import Timer
py> setup = "from __main__ import x, y, z"
py> t1 = Timer("x['c'], x['b'], x['a']", setup)
py> t2 = Timer("y.c, y.b, y.a", setup)
py> t3 = Timer("z.c, z.b, z.a", setup)


And now let's time them:

py> min(t1.repeat())
0.2941127344965935
py> min(t2.repeat())
0.34186235070228577
py> min(t3.repeat())
0.7729006875306368


That's not too shabby. Even the slowest of the three (test t3, the one 
using the namedtuples) takes only 0.26 microseconds per field lookup. 
Times shown are seconds for one million repeats of the test code, or 
nanoseconds per single run. There are three field lookups per test, so 
0.77 nanoseconds/3 is about 0.26 nanoseconds.

If you ever find a piece of code where the difference between 0.1 ns and 
0.26 ns per field lookup is meaningful, I'd like to see it.


> I'm also a bit confused here: obviously tuples are immutable, but one can
> use lists in them... I think that makes those lists' contents immutable?

Nope. It makes the tuple immutable in the sense that it's *direct* 
contents cannot be changed, but mutable in the sense that the contents 
of the tuple can be mutated.

py> t = (1, 2, [])
py> t[2] = ["hello"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
py> t[2].append("hello")
py> t
(1, 2, ['hello'])


> And could one define a namedtuple that included lists that were different
> lengths for different instantiations (like my game results, for example)? 

Naturally. The nametuple doesn't care what you put inside it.


-- 
Steven

From denis.spir at gmail.com  Sat Jan  4 14:13:13 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 04 Jan 2014 14:13:13 +0100
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <20140104130324.GY29356@ando>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
 <52C7DD5D.6000700@gmail.com>
 <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>
 <52C7F57D.4060600@gmail.com>
 <CAO5ffbaNu2vpjm5KKUx20KN+vpbe_fjqE4pP6g1B1fo_6tE6ow@mail.gmail.com>
 <20140104130324.GY29356@ando>
Message-ID: <52C808E9.7010407@gmail.com>

On 01/04/2014 02:03 PM, Steven D'Aprano wrote:
>> >I understand that Python doesn't have composite objects, but neither does
>> >it dislallow my list of lists of ints and lists... which is, I imagine,
>> >very space efficient.
> I'm afraid I have no idea what you mean by Python not having "composite
> objects". What's a composite object?

It was "individual" composite objects: Python requires writing a custom type 
(class), as if there were tons of them.

Eg in Keith Winston's project he would have to define a class for the game tupe 
(ChutesAndLadder) even is there were only one of them (there are many because he 
collects stats, and the game is not really played, his app is more like 
instrumenting a game engine for automagic statistics collection; in a common 
case, there would be only one 'game' object).

Denis

From denis.spir at gmail.com  Sat Jan  4 14:25:56 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 04 Jan 2014 14:25:56 +0100
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <20140104130324.GY29356@ando>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
 <52C7DD5D.6000700@gmail.com>
 <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>
 <52C7F57D.4060600@gmail.com>
 <CAO5ffbaNu2vpjm5KKUx20KN+vpbe_fjqE4pP6g1B1fo_6tE6ow@mail.gmail.com>
 <20140104130324.GY29356@ando>
Message-ID: <52C80BE4.3000305@gmail.com>

On 01/04/2014 02:03 PM, Steven D'Aprano wrote:
>> >I'm also a bit confused here: obviously tuples are immutable, but one can
>> >use lists in them... I think that makes those lists' contents immutable?
> Nope. It makes the tuple immutable in the sense that it's *direct*
> contents cannot be changed, but mutable in the sense that the contents
> of the tuple can be mutated.
>
> py> t = (1, 2, [])
> py> t[2] = ["hello"]
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: 'tuple' object does not support item assignment
> py> t[2].append("hello")
> py> t
> (1, 2, ['hello'])
>
>
>> >And could one define a namedtuple that included lists that were different
>> >lengths for different instantiations (like my game results, for example)?
> Naturally. The nametuple doesn't care what you put inside it.

I used to explain this by making people note that there 2 ways of *changing* a 
given item (or field, or any var for the matter), if its value is complex & 
mutable: *replacing* vs *modifying*:

	l = [1,2,3]
	l = [1,0,3]	# replace (by brand new value/object)
	l[1] = 0	# modify (the value/object itself)

When a symbol's value is simple or mutable, one can only replace it. (You can 
change _only_ the second digit of "123", or its n-th bit in binary 
representation, or the fractional part of "-123.45", less so its sign ;-).

Denis

From alan.gauld at btinternet.com  Sat Jan  4 14:30:38 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 04 Jan 2014 13:30:38 +0000
Subject: [Tutor] python problems on android
In-Reply-To: <52c7ef8b.1e04.147c.65af@fireflyuk.net>
References: <52c7ef8b.1e04.147c.65af@fireflyuk.net>
Message-ID: <la92di$rp8$1@ger.gmane.org>

On 04/01/14 11:24, blechnum at fireflyuk.net wrote:

> At the command line (on my computer)  I can type
>
> h = input(" enter character ")
>
> and when i type a response and enter it, then type h and return, i am
> given back the response i put in.
>
> I type j , get 'j' back
>
> Now on my phone i can do the same.
>
> And here is the odd bit
> If I type a number in, the response will be the number
>
> type 4, get '4' back
>
> but if i  type in a letter I get an error, the same error as if i had
> typed in the response to the command line.
>
> NameError: name '<response to input request>" is not defined


What you describe is the symptoms of using different versions of Python.

In Python v3 (your computer?) input reads a string from the user.
In Python v2 input reads a string and evaluates it as code.
Thus a number evaluates to a number but a string is evaluated like a 
variable name.

Presumably your Android is running your code under a v2 Python interpreter.

You can try putting raw_input() instead of input() in your code to see 
if that fixes it. [input() in v3 is a renaming of input() and the 
original input() function was removed.]

If that works for the simple test case you could try adding this at
the top of your script:

try: input = raw_input
except NameError: pass

But that only addresses one aspect of Python v2/3 incompatibility so 
there will probably be other fixes needed. The best thing is to align 
Python versions.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From davea at davea.name  Sat Jan  4 14:34:43 2014
From: davea at davea.name (Dave Angel)
Date: Sat, 04 Jan 2014 08:34:43 -0500
Subject: [Tutor] python problems on android
In-Reply-To: <52c7fb9d.1e04.18d0.4920@fireflyuk.net>
References: <52c7fb9d.1e04.18d0.4920@fireflyuk.net>
 <52c7fb9d.1e04.18d0.4920@fireflyuk.net>
Message-ID: <almarsoft.8979102103157223479@news.gmane.org>

On Sat, 04 Jan 2014 12:16:29 +0000, blechnum at fireflyuk.net wrote:
> Thank you. I see, it was running python 3.x
>  when that  didn't work I uninstalled it


>  and used SL4a to reinstall

> it installed Python 2.x

> So raw_input should work instead of input

If you're stuck with 2.x then you could use raw_input (). But there 
are many other differences. If you're learning 3.x you should 
reinstall 3.x.

Or doesn't slate work with a current python?

-- 
DaveA


From christian.h.alexander at gmail.com  Sat Jan  4 15:10:36 2014
From: christian.h.alexander at gmail.com (Christian Alexander)
Date: Sat, 4 Jan 2014 09:10:36 -0500
Subject: [Tutor] python 3.3 split method confusion
Message-ID: <CABSj3_7kbrV9ExjAR-vH4atUm+hnq0gYJXauZ=wZk+FqXnNeeA@mail.gmail.com>

Hello fellow tutors,

I am curious to know why the split() method does not output the arbitrary
delimiter that is passed as an argument?  For example:

string1 = "this,is,just,another,string"
print(string1.split(","))

I understand the the above code simply states, "break at every ' , ' ".
 But why is the delimiter not printed as well?

-- 
Regards,

Christian Alexander
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140104/0961ba11/attachment.html>

From alan.gauld at btinternet.com  Sat Jan  4 15:25:19 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 04 Jan 2014 14:25:19 +0000
Subject: [Tutor] python 3.3 split method confusion
In-Reply-To: <CABSj3_7kbrV9ExjAR-vH4atUm+hnq0gYJXauZ=wZk+FqXnNeeA@mail.gmail.com>
References: <CABSj3_7kbrV9ExjAR-vH4atUm+hnq0gYJXauZ=wZk+FqXnNeeA@mail.gmail.com>
Message-ID: <la95k3$r0i$1@ger.gmane.org>

On 04/01/14 14:10, Christian Alexander wrote:

> I am curious to know why the split() method does not output the
> arbitrary delimiter that is passed as an argument?  For example:

Because in most cases you don't want it and would have to strip
it off each element manually after the event.

I suppose they could have had a preserve parameter with a
default value of False for the few cases where you want to
keep it.

But in the majority of cases split is used where we read a line
of input from a data file where the data fields are separated
by some arbitrary character, usually comma, tab or pipe. The
important bit is the data not the separator.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From akleider at sonic.net  Sat Jan  4 18:21:41 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sat, 04 Jan 2014 09:21:41 -0800
Subject: [Tutor] simple arg problem
In-Reply-To: <20140104044532.GQ29356@ando>
References: <CAO5ffbbHkob+jw+hRh9YozCVkxXhjTpnJTNhqnKOCd7qS6HHjQ@mail.gmail.com>
 <CAO5ffbbSs150eE-o-rLokG4Y090OfLSd-0YRtZ3F30mwRU80GQ@mail.gmail.com>
 <20140104044532.GQ29356@ando>
Message-ID: <2fe5fea2bfc32ed32af672c4360abd3b@sonic.net>

On 2014-01-03 20:45, Steven D'Aprano wrote:
> On Fri, Jan 03, 2014 at 09:56:25PM -0500, Keith Winston wrote:
...
  >>>
> 
> Eryksun has already solved your immediate problem, but I'd like to 
> point
> out that the above has a couple of code smells.
> 
> Are you familiar with the concept of a code smell? Code which smells
> wrong might not be wrong, but it's worth giving it a good hard long 
> look
> just to be sure. Like Grandma used to say about your nappies, "If it
> stinks, change it", code smells usually suggest there's a problem with
> the code.
> 
> http://www.codinghorror.com/blog/2006/05/code-smells.html

In the reference you site, under "Oddball Solution" mention is made of 
"adaptor model."
Is this the same as what is described here, 
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93adapter, under 
the name of "Model-View-Adaptor?"

I don't understand the connection, so perhaps I got the wrong reference. 
Light shed on the issue would be appreciated.
cheers,
Alex


From alan.gauld at btinternet.com  Sat Jan  4 19:56:36 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 04 Jan 2014 18:56:36 +0000
Subject: [Tutor] simple arg problem
In-Reply-To: <2fe5fea2bfc32ed32af672c4360abd3b@sonic.net>
References: <CAO5ffbbHkob+jw+hRh9YozCVkxXhjTpnJTNhqnKOCd7qS6HHjQ@mail.gmail.com>
 <CAO5ffbbSs150eE-o-rLokG4Y090OfLSd-0YRtZ3F30mwRU80GQ@mail.gmail.com>
 <20140104044532.GQ29356@ando> <2fe5fea2bfc32ed32af672c4360abd3b@sonic.net>
Message-ID: <la9lgo$u2l$1@ger.gmane.org>

On 04/01/14 17:21, Alex Kleider wrote:

> In the reference you site, under "Oddball Solution" mention is made of
> "adaptor model."
> Is this the same as what is described here,
> http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93adapter, under
> the name of "Model-View-Adaptor?"

I haven't read it but I'm guessing its more likely associated
with the adapter (or wrapper) pattern:

http://en.wikipedia.org/wiki/Adapter_pattern

just guessing though,

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From akleider at sonic.net  Sat Jan  4 20:02:35 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sat, 04 Jan 2014 11:02:35 -0800
Subject: [Tutor] simple arg problem
In-Reply-To: <la9lgo$u2l$1@ger.gmane.org>
References: <CAO5ffbbHkob+jw+hRh9YozCVkxXhjTpnJTNhqnKOCd7qS6HHjQ@mail.gmail.com>
 <CAO5ffbbSs150eE-o-rLokG4Y090OfLSd-0YRtZ3F30mwRU80GQ@mail.gmail.com>
 <20140104044532.GQ29356@ando> <2fe5fea2bfc32ed32af672c4360abd3b@sonic.net>
 <la9lgo$u2l$1@ger.gmane.org>
Message-ID: <d7cc6ce01baf604e51dd80bee56a508a@sonic.net>

On 2014-01-04 10:56, Alan Gauld wrote:
> On 04/01/14 17:21, Alex Kleider wrote:
> 
>> In the reference you site, under "Oddball Solution" mention is made of
>> "adaptor model."
>> Is this the same as what is described here,
>> http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93adapter, under
>> the name of "Model-View-Adaptor?"
> 
> I haven't read it but I'm guessing its more likely associated
> with the adapter (or wrapper) pattern:
> 
> http://en.wikipedia.org/wiki/Adapter_pattern
> 
> just guessing though,

Yes, that fits; i.e. makes more sense.
thanks.


From akleider at sonic.net  Sat Jan  4 20:26:35 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sat, 04 Jan 2014 11:26:35 -0800
Subject: [Tutor] encoding question
Message-ID: <0f67356033ea2385876180615faf3ea3@sonic.net>

Any suggestions as to a better way to handle the problem of encoding in 
the following context would be appreciated.  The problem arose because 
'Bogota' is spelt with an acute accent on the 'a'.

$ cat IP_info.py3
#!/usr/bin/env python3
# -*- coding : utf -8 -*-
# file: 'IP_info.py3'  a module.

import urllib.request

url_format_str = \
     'http://api.hostip.info/get_html.php?ip=%s&position=true'

def ip_info(ip_address):
     """
Returns a dictionary keyed by Country, City, Lat, Long and IP.

Depends on http://api.hostip.info (which returns the following:
'Country: UNITED STATES (US)\nCity: Santa Rosa, CA\n\nLatitude:
38.4486\nLongitude: -122.701\nIP: 76.191.204.54\n'.)
THIS COULD BREAK IF THE WEB SITE GOES AWAY!!!
"""
     response =  urllib.request.urlopen(url_format_str %\
                                    (ip_address, )).read()
     sp = response.splitlines()
     country = city = lat = lon = ip = ''
     for item in sp:
         if item.startswith(b"Country:"):
             try:
                 country = item[9:].decode('utf-8')
             except:
                 print("Exception raised.")
                 country = item[9:]
         elif item.startswith(b"City:"):
             try:
                 city = item[6:].decode('utf-8')
             except:
                 print("Exception raised.")
                 city = item[6:]
         elif item.startswith(b"Latitude:"):
             try:
                 lat = item[10:].decode('utf-8')
             except:
                 print("Exception raised.")
                 lat = item[10]
         elif item.startswith(b"Longitude:"):
             try:
                 lon = item[11:].decode('utf-8')
             except:
                 print("Exception raised.")
                 lon = item[11]
         elif item.startswith(b"IP:"):
             try:
                 ip = item[4:].decode('utf-8')
             except:
                 print("Exception raised.")
                 ip = item[4:]
     return {"Country" : country,
             "City" : city,
             "Lat" : lat,
             "Long" : lon,
             "IP" : ip            }

if __name__ == "__main__":
     addr =  "201.234.178.62"
     print ("""    IP address is %(IP)s:
         Country: %(Country)s;  City: %(City)s.
         Lat/Long: %(Lat)s/%(Long)s""" % ip_info(addr))
"""

The output I get on an Ubuntu 12.4LTS system is as follows:
alex at x301:~/Python/Parse$ ./IP_info.py3
Exception raised.
     IP address is 201.234.178.62:
         Country: COLOMBIA (CO);  City: b'Bogot\xe1'.
         Lat/Long: 10.4/-75.2833


I would have thought that utf-8 could handle the 'a-acute'.

Thanks,
alex

From eryksun at gmail.com  Sat Jan  4 21:01:15 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 4 Jan 2014 15:01:15 -0500
Subject: [Tutor] encoding question
In-Reply-To: <0f67356033ea2385876180615faf3ea3@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
Message-ID: <CACL+1auCaLbj1XHwiz4Sa6F7haY4qwaUaLcsACNU8TtCCi+pNQ@mail.gmail.com>

On Sat, Jan 4, 2014 at 2:26 PM, Alex Kleider <akleider at sonic.net> wrote:
> The output I get on an Ubuntu 12.4LTS system is as follows:
> alex at x301:~/Python/Parse$ ./IP_info.py3
> Exception raised.
>     IP address is 201.234.178.62:
>         Country: COLOMBIA (CO);  City: b'Bogot\xe1'.
>         Lat/Long: 10.4/-75.2833
>
>
> I would have thought that utf-8 could handle the 'a-acute'.

b'\xe1' is Latin-1. Look in the response headers:

    url = 'http://api.hostip.info/get_html.php?ip=201.234.178.62&position=true'

    >>> response = urllib.request.urlopen(url)
    >>> response.headers.get_charsets()
    ['iso-8859-1']

    >>> encoding = response.headers.get_charsets()[0]
    >>> sp = response.read().decode(encoding).splitlines()
    >>> sp[1]
    'City: Bogot?'

From akleider at sonic.net  Sat Jan  4 21:11:51 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sat, 04 Jan 2014 12:11:51 -0800
Subject: [Tutor] code smells: Object-orientation Abusers: switch statements
In-Reply-To: <52c7ef8b.1e04.147c.65af@fireflyuk.net>
References: <52c7ef8b.1e04.147c.65af@fireflyuk.net>
Message-ID: <29a9c8d11c04264670dc67d82aa30551@sonic.net>

Continuing to look into the subject of code smells, I ran across this:
"The situation where switch statements or type codes are needed should 
be handled by creating subclasses."
@ http://www.soberit.hut.fi/mmantyla/BadCodeSmellsTaxonomy.htm

Assuming I am correct that in Python, switch statements must be 
implemented as a series of if; elif; .. statements, how is it that this 
can be avoided by creating subclasses?
tks
alex


From alan.gauld at btinternet.com  Sat Jan  4 21:47:52 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 04 Jan 2014 20:47:52 +0000
Subject: [Tutor] code smells: Object-orientation Abusers: switch
	statements
In-Reply-To: <29a9c8d11c04264670dc67d82aa30551@sonic.net>
References: <52c7ef8b.1e04.147c.65af@fireflyuk.net>
 <29a9c8d11c04264670dc67d82aa30551@sonic.net>
Message-ID: <la9s1c$ueo$1@ger.gmane.org>

On 04/01/14 20:11, Alex Kleider wrote:

> Assuming I am correct that in Python, switch statements must be
> implemented as a series of if; elif; .. statements, how is it that this
> can be avoided by creating subclasses?


Its called polymorphism and is one of the most powerful advantages of 
OOP since case or switch statements are one of the most fault prone 
structures in procedural programming.

You can see an example in my OOP topic in my tutor under the heading
'Same thing, Differenmt thing'

http://www.alan-g.me.uk/tutor/tutclass.htm

It uses a Shape class and several subclasses - Square, Triangle, Circle.
It calculates the areas of a list of these shapes.

Without OOP you would need to do something like

for shape in shapes:
     if shape['type'] == CIRCLE:
         result = circle_area(shape['radius'])
     elif shape['type'] == SQUARE:
         result = square_area(shape['length'])
     elif ....

But with OOP we simply call each shapes area method and
the interpreter works out which method to call:

for shape in shapes:
  result = shape.area()

This has several benefits.

First we can add new shape types and not have to change any of the 
application level code. The new shapes will supply their own area() 
methods and all is well.

Second if we use the case style and need to modify the set of tests, we 
probably will need to do this in all sorts of places in our code.
It's easy to forget one statement in a rarely used backwater...

Thirdly polymorphism means we never inadvertently miss out a case.
OOP will handle all object types in all situations. Cases can only 
handle the cases they have been programmed for.

Finally the case statement require an intimate knowledge of both the 
attributes used for the test (if they ever get renamed, ouch!)
and also the calling signatures (including how many and what type
of parameters they have and the names) of the area functions. The OOP 
area method can use the internal attributes so no arguments need be 
provided. (The alternative for the switch is that the functions
rely on the incoming object being cast or type converted to
the correct shape subtype, which is almost as unreliable as
reading the correct attributes). Even worse is that for short
functions like area it's often tempting to inline the calculation
within the case block. But then the same calculation is needed
somewhere else and we then get duplicate code to maintain as
well!


HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Sat Jan  4 21:54:08 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 04 Jan 2014 20:54:08 +0000
Subject: [Tutor] code smells: Object-orientation Abusers: switch
	statements
In-Reply-To: <la9s1c$ueo$1@ger.gmane.org>
References: <52c7ef8b.1e04.147c.65af@fireflyuk.net>
 <29a9c8d11c04264670dc67d82aa30551@sonic.net> <la9s1c$ueo$1@ger.gmane.org>
Message-ID: <la9sd4$2v7$1@ger.gmane.org>

I meant to add...

On 04/01/14 20:47, Alan Gauld wrote:

> Its called polymorphism and is one of the most powerful advantages of
> OOP since case or switch statements are one of the most fault prone
> structures in procedural programming.
> ...
> Without OOP you would need to do something like
>
> for shape in shapes:
>      if shape['type'] == CIRCLE:
>          result = circle_area(shape['radius'])
>      elif shape['type'] == SQUARE:
>          result = square_area(shape['length'])
>      elif ....
>
> But with OOP we simply call each shapes area method and
> the interpreter works out which method to call:
>
> for shape in shapes:
>   result = shape.area()

This reduction in code in switch statements (and similar savings in 
other scenarios) is one of the reasons that OOP solutions are often much 
shorter than non OOP programs for non-trivial cases.

Beginners often don't see these benefits because their short programs 
only have one or two classes and the overhead of creating the classes 
dwarfs the savings that might accrue. But in a big project where lots of 
if/else type situations may arise the code savings can easily add up to 
20-30%.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From akleider at sonic.net  Sat Jan  4 21:44:29 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sat, 04 Jan 2014 12:44:29 -0800
Subject: [Tutor] encoding question
In-Reply-To: <CACL+1auCaLbj1XHwiz4Sa6F7haY4qwaUaLcsACNU8TtCCi+pNQ@mail.gmail.com>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <CACL+1auCaLbj1XHwiz4Sa6F7haY4qwaUaLcsACNU8TtCCi+pNQ@mail.gmail.com>
Message-ID: <fc502d56abaefda8bedcc2ac66f9e883@sonic.net>

On 2014-01-04 12:01, eryksun wrote:
> On Sat, Jan 4, 2014 at 2:26 PM, Alex Kleider <akleider at sonic.net> 
> wrote:
.....
> 
> b'\xe1' is Latin-1. Look in the response headers:
> 
>     url = 
> 'http://api.hostip.info/get_html.php?ip=201.234.178.62&position=true'
> 
>     >>> response = urllib.request.urlopen(url)
>     >>> response.headers.get_charsets()
>     ['iso-8859-1']
> 
>     >>> encoding = response.headers.get_charsets()[0]
>     >>> sp = response.read().decode(encoding).splitlines()
>     >>> sp[1]
>     'City: Bogot?'

Thank you very much.  Now things are more clear.
cheers,
alex

From steve at pearwood.info  Sun Jan  5 00:52:44 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 5 Jan 2014 10:52:44 +1100
Subject: [Tutor] encoding question
In-Reply-To: <0f67356033ea2385876180615faf3ea3@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
Message-ID: <20140104235243.GA29356@ando>

On Sat, Jan 04, 2014 at 11:26:35AM -0800, Alex Kleider wrote:
> Any suggestions as to a better way to handle the problem of encoding in 
> the following context would be appreciated.

Python gives you lots of useful information when errors occur, but 
unfortunately your code throws that information away and replaces it 
with a totally useless message:

>             try:
>                 country = item[9:].decode('utf-8')
>             except:
>                 print("Exception raised.")

Oh great. An exception was raised. What sort of exception? What error 
message did it have? Why did it happen? Nobody knows, because you throw 
it away.

Never, never, never do this. If you don't understand an exception, you 
have no business covering it up and hiding that it took place. Never use 
a bare try...except, always catch the *smallest* number of specific 
exception types that make sense. Better is to avoid catching exceptions 
at all: an exception (usually) means something has gone wrong. You 
should aim to fix the problem *before* it blows up, not after.

I'm reminded of a quote:

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

Your code is incorrect, it does the wrong thing, but it doesn't crash, 
it just covers up the fact that an exception occured.


> The output I get on an Ubuntu 12.4LTS system is as follows:
> alex at x301:~/Python/Parse$ ./IP_info.py3
> Exception raised.
>     IP address is 201.234.178.62:
>         Country: COLOMBIA (CO);  City: b'Bogot\xe1'.
>         Lat/Long: 10.4/-75.2833
> 
> 
> I would have thought that utf-8 could handle the 'a-acute'.

Of course it can:

py> 'Bogot?'.encode('utf-8')
b'Bogot\xc3\xa1'

py> b'Bogot\xc3\xa1'.decode('utf-8')
'Bogot?'


But you don't have UTF-8. You have something else, and trying to decode 
it using UTF-8 fails.

py> b'Bogot\xe1'.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe1 in position 5: 
unexpected end of data


More to follow...




-- 
Steven

From akleider at sonic.net  Sun Jan  5 01:15:30 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sat, 04 Jan 2014 16:15:30 -0800
Subject: [Tutor] encoding question
In-Reply-To: <20140104235243.GA29356@ando>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando>
Message-ID: <6ca8d91d0c974a627f3909877e2256ab@sonic.net>

On 2014-01-04 15:52, Steven D'Aprano wrote:

> Oh great. An exception was raised. What sort of exception? What error
> message did it have? Why did it happen? Nobody knows, because you throw
> it away.
> 
> Never, never, never do this. If you don't understand an exception, you
> have no business covering it up and hiding that it took place. Never 
> use
> a bare try...except, always catch the *smallest* number of specific
> exception types that make sense. Better is to avoid catching exceptions
> at all: an exception (usually) means something has gone wrong. You
> should aim to fix the problem *before* it blows up, not after.
> 
> I'm reminded of a quote:
> 
> "I find it amusing when novice programmers believe their main job is
> preventing programs from crashing. ... More experienced programmers
> realize that correct code is great, code that crashes could use
> improvement, but incorrect code that doesn't crash is a horrible
> nightmare." -- Chris Smith
> 
> Your code is incorrect, it does the wrong thing, but it doesn't crash,
> it just covers up the fact that an exception occured.
> 
> 
>> The output I get on an Ubuntu 12.4LTS system is as follows:
>> alex at x301:~/Python/Parse$ ./IP_info.py3
>> Exception raised.
>>     IP address is 201.234.178.62:
>>         Country: COLOMBIA (CO);  City: b'Bogot\xe1'.
>>         Lat/Long: 10.4/-75.2833
>> 
>> 
>> I would have thought that utf-8 could handle the 'a-acute'.
> 
> Of course it can:
> 
> py> 'Bogot?'.encode('utf-8')

I'm interested in knowing how you were able to enter the above line 
(assuming you have a key board similar to mine.)


> b'Bogot\xc3\xa1'
> 
> py> b'Bogot\xc3\xa1'.decode('utf-8')
> 'Bogot?'
> 
> 
> But you don't have UTF-8. You have something else, and trying to decode
> it using UTF-8 fails.
> 
> py> b'Bogot\xe1'.decode('utf-8')
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe1 in position 5:
> unexpected end of data
> 
> 
> More to follow...


I very much agree with your remarks.
In a pathetic attempt at self defence I just want to mention that what I 
presented wasn't what I thought was a solution.
Rather it was an attempt to figure out what the problem was as a 
preliminary step to fixing it.
With help from you and others, I was successful in doing this.
And for that help, I thank all list participants very much.


From eryksun at gmail.com  Sun Jan  5 01:42:31 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 4 Jan 2014 19:42:31 -0500
Subject: [Tutor] encoding question
In-Reply-To: <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando>
 <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
Message-ID: <CACL+1asYUXCVffcB4jJooKiCndUtohrChx_RAXd8q4e=Do=QpA@mail.gmail.com>

On Sat, Jan 4, 2014 at 7:15 PM, Alex Kleider <akleider at sonic.net> wrote:
>>
>> py> 'Bogot?'.encode('utf-8')
>
> I'm interested in knowing how you were able to enter the above line
> (assuming you have a key board similar to mine.)

I use an international keyboard layout:

https://en.wikipedia.org/wiki/QWERTY#US-International

One could also copy and paste from a printed literal:

    >>> 'Bogot\xe1'
    'Bogot?'

Or more verbosely:

    >>> 'Bogot\N{latin small letter a with acute}'
   'Bogot?'

From steve at pearwood.info  Sun Jan  5 01:44:45 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 5 Jan 2014 11:44:45 +1100
Subject: [Tutor] encoding question
In-Reply-To: <0f67356033ea2385876180615faf3ea3@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
Message-ID: <20140105004444.GB29356@ando>

Following my previous email...

On Sat, Jan 04, 2014 at 11:26:35AM -0800, Alex Kleider wrote:
> Any suggestions as to a better way to handle the problem of encoding in 
> the following context would be appreciated.  The problem arose because 
> 'Bogota' is spelt with an acute accent on the 'a'.

Eryksun has given the right answer for how to extract the encoding from 
the webpage's headers. That will help 9 times out of 10. But 
unfortunately sometimes webpages will lack an encoding header, or they 
will lie, or the text will be invalid for that encoding. What to do 
then?

Let's start by factoring out the repeated code in your giant for-loop 
into something more manageable and maintainable:

>     sp = response.splitlines()
>     country = city = lat = lon = ip = ''
>     for item in sp:
>         if item.startswith(b"Country:"):
>             try:
>                 country = item[9:].decode('utf-8')
>             except:
>                 print("Exception raised.")
>                 country = item[9:]
>         elif item.startswith(b"City:"):
>             try:
>                 city = item[6:].decode('utf-8')
>             except:
>                 print("Exception raised.")
>                 city = item[6:]

and so on, becomes:

    encoding = ...  # as per Eryksun's email
    sp = response.splitlines()
    country = city = lat = lon = ip = ''
    for item in sp:
        key, value = item.split(':', 1)
        key = key.decode(encoding).strip()
        value = value.decode(encoding).strip()
        if key == 'Country':
            country = value
        elif key == 'City':
            city = value
        elif key == 'Latitude':
            lat = value
        elif key = "Longitude":
            lon = value
        elif key = 'IP':
            ip = value
        else:
            raise ValueError('unknown key "%s" found' % key)
    return {"Country" : country,
            "City" : city,
            "Lat" : lat,
            "Long" : lon,
            "IP" : ip
            }


But we can do better than that!

    encoding = ...  # as per Eryksun's email
    sp = response.splitlines()
    record = {"Country": None, "City": None, "Latitude": None, 
              "Longitude": None, "IP": None}
    for item in sp:
        key, value = item.split(':', 1)
        key = key.decode(encoding).strip()
        value = value.decode(encoding).strip()
        if key in record:
            record[key] = value
        else:
            raise ValueError('unknown key "%s" found' % key)
    if None in list(record.values()):
        for key, value in record.items():
            if value is None: break
        raise ValueError('missing key in record: %s' % key)
    return record


This simplifies the code a lot, and adds some error-handling. It may be 
appropriate for your application to handle missing keys by using some 
default value, such as an empty string, or some other value that cannot 
be mistaken for an actual value, say "*missing*". But since I don't know 
your application's needs, I'm going to leave that up to you. Better to 
start strict and loosen up later, than start too loose and never realise 
that errors are occuring.

I've also changed the keys "Lat" and "Lon" to "Latitude" and 
"Longitude". If that's a problem, it's easy to fix. Just before 
returning the record, change the key:

    record['Lat'] = record.pop('Latitude')

and similar for Longitude.

Now that the code is simpler to read and maintain, we can start dealing 
with the risk that the encoding will be missing or wrong.

A missing encoding is easy to handle: just pick a default encoding, and 
hope it is the right one. UTF-8 is a good choice. (It's the only 
*correct* choice, everybody should be using UTF-8, but alas they often 
don't.) So modify Eryksun's code snippet to return 'UTF-8' if the header 
is missing, and you should be good.

How to deal with incorrect encodings? That can happen when the website 
creator *thinks* they are using a certain encoding, but somehow invalid 
bytes for that encoding creep into the data. That gives us a few 
different strategies:

(1) The third-party "chardet" module can analyse text and try to guess 
what encoding it *actually* is, rather than what encoding it claims to 
be. This is what Firefox and other web browsers do, because there are an 
awful lot of shitty websites out there. But it's not foolproof, so even 
if it guesses correctly, you still have to deal with invalid data.

(2) By default, the decode method will raise an exception. You can catch 
the exception and try again with a different encoding:

    for codec in (encoding, 'utf-8', 'latin-1'):
        try:
            key = key.decode(codec)
        except UnicodeDecodeError:
            pass
        else:
            break

Latin-1 should be last, because it has the nice property that it will 
*always* succeed. That doesn't mean it will give you the right 
characters, as intended by the person who wrote the website, just that 
it will always give you *some* characters. They may be completely wrong, 
in other words "mojibake", but they'll be something.

An example of mojibake:

py> b = 'Bogot?'.encode('utf-8')
py> b.decode('latin-1')
'Bogot??'


Perhaps a better way is to use the decode/encode error handler. Instead 
of just calling the decode method, you can specify what to do when an 
error occurs: raise an exception, ignore the bad bytes, or replace them 
with some sort of placeholder. We can see the difference here:

py> b = 'Bogot?'.encode('latin-1')
py> print(b)
b'Bogot\xe1'
py> b.decode('utf-8', 'strict')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe1 in position 5: 
unexpected end of data
py> b.decode('utf-8', 'ignore')
'Bogot'
py> b.decode('utf-8', 'replace')
'Bogot?'


My suggestion is to use the 'replace' error handler.

Armed with this, you should be able to write good solid code that can 
handle most encoding-related errors.


-- 
Steven

From christian.h.alexander at gmail.com  Sat Jan  4 22:38:29 2014
From: christian.h.alexander at gmail.com (Christian Alexander)
Date: Sat, 4 Jan 2014 16:38:29 -0500
Subject: [Tutor] python 3.3 split method confusion
In-Reply-To: <la95k3$r0i$1@ger.gmane.org>
References: <CABSj3_7kbrV9ExjAR-vH4atUm+hnq0gYJXauZ=wZk+FqXnNeeA@mail.gmail.com>
 <la95k3$r0i$1@ger.gmane.org>
Message-ID: <CABSj3_5+0cGEUh3yNfDTM4=aegwYDygh87iBAWgUDjFXSJpTFw@mail.gmail.com>

Thank you for clarifying my inquiry.  I was just unable to find the reason
as to why the built-in excludes the delimiter from the outpu.


On Sat, Jan 4, 2014 at 9:25 AM, Alan Gauld <alan.gauld at btinternet.com>wrote:

> On 04/01/14 14:10, Christian Alexander wrote:
>
>  I am curious to know why the split() method does not output the
>> arbitrary delimiter that is passed as an argument?  For example:
>>
>
> Because in most cases you don't want it and would have to strip
> it off each element manually after the event.
>
> I suppose they could have had a preserve parameter with a
> default value of False for the few cases where you want to
> keep it.
>
> But in the majority of cases split is used where we read a line
> of input from a data file where the data fields are separated
> by some arbitrary character, usually comma, tab or pipe. The
> important bit is the data not the separator.
>
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> 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
>



-- 
Regards,

Christian Alexander
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140104/ba723baf/attachment.html>

From steve at pearwood.info  Sun Jan  5 02:49:49 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 5 Jan 2014 12:49:49 +1100
Subject: [Tutor] encoding question
In-Reply-To: <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
Message-ID: <20140105014945.GC29356@ando>

On Sat, Jan 04, 2014 at 04:15:30PM -0800, Alex Kleider wrote:

> >py> 'Bogot?'.encode('utf-8')
> 
> I'm interested in knowing how you were able to enter the above line 
> (assuming you have a key board similar to mine.)

I'm running Linux, and I use the KDE or Gnome character selector, 
depending on which computer I'm using. They give you a graphical window 
showing a screenful of characters at a time, depending on which 
application I'm using you can search for characters by name or property, 
then copy them into the clipboard to paste them into another 
application.

I can also use the "compose" key. My keyboard doesn't have an actual key 
labelled compose, but my system is set to use the right-hand Windows key 
(between Alt and the menu key) as the compose key. (Why the left-hand 
Windows key isn't set to do the same thing is a mystery to me.) So if I 
type:

<Compose> 'a

I get ?.

The problem with the compose key is that it's not terribly intuitive. 
Sure, a few of them are: <Compose> 1 2 gives ? but how do I get ? (pi)? 
<Compose> p doesn't work.



-- 
Steven

From akleider at sonic.net  Sun Jan  5 03:31:13 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sat, 04 Jan 2014 18:31:13 -0800
Subject: [Tutor] encoding question
In-Reply-To: <20140105014945.GC29356@ando>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando>
Message-ID: <9e202379421c33cda3c81ecfb0a938c6@sonic.net>

A heartfelt thank you to those of you that have given me much to ponder 
with your helpful responses.
In the mean time I've rewritten my procedure using a different approach 
all together.  I'd be interested in knowing if you think it's worth 
keeping or do you suggest I use your revisions to my original hack?

I've been maintaining both a Python3 and a Python2.7 version.  The 
latter has actually opened my eyes to more complexities. Specifically 
the need to use unicode strings rather than Python2.7's default ascii.

Here it is:
alex at x301:~/Python/Parse$ cat ip_info.py
#!/usr/bin/env python
# -*- coding : utf -8 -*-

import re
import urllib2

url_format_str = \
     u'http://api.hostip.info/get_html.php?ip=%s&position=true'

info_exp = r"""
Country:[ ](?P<country>.*)
[\n]
City:[ ](?P<city>.*)
[\n]
[\n]
Latitude:[ ](?P<lat>.*)
[\n]
Longitude:[ ](?P<lon>.*)
[\n]
IP:[ ](?P<ip>.*)
         """
info_pattern = re.compile(info_exp, re.VERBOSE).search

def ip_info(ip_address):
     """
Returns a dictionary keyed by Country, City, Lat, Long and IP.

Depends on http://api.hostip.info (which returns the following:
'Country: UNITED STATES (US)\nCity: Santa Rosa, CA\n\nLatitude:
38.4486\nLongitude: -122.701\nIP: 76.191.204.54\n'.)
THIS COULD BREAK IF THE WEB SITE GOES AWAY!!!
"""
     response =  urllib2.urlopen(url_format_str %\
                                    (ip_address, ))
     encoding = response.headers.getparam('charset')

     info = info_pattern(response.read().decode(encoding))
     return {"Country" : unicode(info.group("country")),
             "City" : unicode(info.group("city")),
             "Lat" : unicode(info.group("lat")),
             "Lon" : unicode(info.group("lon")),
             "IP" : unicode(info.group("ip"))            }

if __name__ == "__main__":
     print """    IP address is %(IP)s:
         Country: %(Country)s;  City: %(City)s.
         Lat/Long: %(Lat)s/%(Lon)s""" % ip_info("201.234.178.62")

Apart from soliciting your general comments, I'm also interested to know 
exactly what the line
# -*- coding : utf -8 -*-
really indicates or more importantly, is it true, since I am using vim 
and I assume things are encoded as ascii?

I've discovered that with Ubuntu it's very easy to switch from English 
(US) to English (US, international with dead keys) with just two clicks 
so thanks for that tip as well.




From dyoo at hashcollision.org  Sun Jan  5 03:44:18 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 4 Jan 2014 18:44:18 -0800
Subject: [Tutor] encoding question
In-Reply-To: <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando>
 <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando>
 <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
Message-ID: <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>

Hi Alex,


According to:

    http://www.hostip.info/use.html

there is a JSON-based interface.  I'd recommend using that one!  JSON
is a format that's easy for machines to decode.  The format you're
parsing is primarily for humans, and who knows if that will change in
the future to make it easier to read?

Not only is JSON probably more reliable to parse, but the code itself
should be fairly straightforward.  For example:

#########################################################
## In Python 2.7
##
>>> import json
>>> import urllib
>>> response = urllib.urlopen('http://api.hostip.info/get_json.php')
>>> info = json.load(response)
>>> info
{u'country_name': u'UNITED STATES', u'city': u'Mountain View, CA',
u'country_code': u'US', u'ip': u'216.239.45.81'}
#########################################################


Best of wishes!

From dyoo at hashcollision.org  Sun Jan  5 03:50:41 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 4 Jan 2014 18:50:41 -0800
Subject: [Tutor] encoding question
In-Reply-To: <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando>
 <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando>
 <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
Message-ID: <CAGZAPF6M+R0VtL24s6o6uwoVz+n6DLv99dVEGRs9+fSuPO6row@mail.gmail.com>

You were asking earlier about the line:

    # -*- coding : utf -8 -*-

See PEP 263:

    http://www.python.org/dev/peps/pep-0263/
    http://docs.python.org/release/2.3/whatsnew/section-encodings.html

It's a line that tells Python how to interpret the bytes of your
source program.  It allows us to write unicode literal strings
embedded directly in the program source itself.

From dyoo at hashcollision.org  Sun Jan  5 04:03:16 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 4 Jan 2014 19:03:16 -0800
Subject: [Tutor] python 3.3 split method confusion
In-Reply-To: <CABSj3_5+0cGEUh3yNfDTM4=aegwYDygh87iBAWgUDjFXSJpTFw@mail.gmail.com>
References: <CABSj3_7kbrV9ExjAR-vH4atUm+hnq0gYJXauZ=wZk+FqXnNeeA@mail.gmail.com>
 <la95k3$r0i$1@ger.gmane.org>
 <CABSj3_5+0cGEUh3yNfDTM4=aegwYDygh87iBAWgUDjFXSJpTFw@mail.gmail.com>
Message-ID: <CAGZAPF57y3XfqOHR=+ZK4HXfdFFthzQ9RvEfuQWAgKmvFYdKew@mail.gmail.com>

One of the common cases for split() is to break a line into a list of
words, for example.

#####################################
>>> 'hello this is a test'.split()
['hello', 'this', 'is', 'a', 'test']
#####################################

The Standard Library can not do everything that we can conceive of as
being useful, because that set is fairly large.

If the Standard Library doesn't do it, we'll probably need to do it
ourselves, or find someone who has done it already.


##########################################
>>> def mysplit(s, delim):
...     start = 0
...     while True:
...         index = s.find(delim, start)
...         if index != -1:
...             yield s[start:index]
...             yield delim
...             start = index + len(delim)
...         else:
...             yield s[start:]
...             return
...
>>> list(mysplit("this,is,a,test", ","))
['this', ',', 'is', ',', 'a', ',', 'test']
##########################################

From davea at davea.name  Sun Jan  5 04:08:20 2014
From: davea at davea.name (Dave Angel)
Date: Sat, 04 Jan 2014 22:08:20 -0500
Subject: [Tutor] encoding question
In-Reply-To: <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
Message-ID: <almarsoft.4121042018064574987@news.gmane.org>

On Sat, 04 Jan 2014 18:31:13 -0800, Alex Kleider <akleider at sonic.net> 
wrote:
> exactly what the line
> # -*- coding : utf -8 -*-
> really indicates or more importantly, is it true, since I am using 
vim 
> and I assume things are encoded as ascii?

I don't know vim specifically,  but I'm 99% sure it will let you 
specify the encoding,. Certainly emacs does, so I'd not expect vim to 
fall behind on such a fundamental point.   Anyway it's also likely 
that it defaults to utf for new files.  Anyway your job is to make 
sure that the encoding line matches what the editor is using.  Emacs 
also looks in the first few lines for that same encoding line, so if 
you format it carefully, it'll just work. Easy to test anyway for 
yourself.  Just paste some international characters into a literal 
string.

-- 
DaveA


From dyoo at hashcollision.org  Sun Jan  5 04:19:13 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 4 Jan 2014 19:19:13 -0800
Subject: [Tutor] code smells: Object-orientation Abusers: switch
	statements
In-Reply-To: <29a9c8d11c04264670dc67d82aa30551@sonic.net>
References: <52c7ef8b.1e04.147c.65af@fireflyuk.net>
 <29a9c8d11c04264670dc67d82aa30551@sonic.net>
Message-ID: <CAGZAPF52OWzY_8582Nv0hEm-HCcfv3x16i_UQxA52wDq81MehQ@mail.gmail.com>

Compare:

###############################################
class Dog(object): pass
class Cat(object): pass
class Cow(object): pass

def sayHi(animal):
    if isinstance(animal, Dog):
        print("Woof")
    elif isinstance(animal, Cat):
        print("Meow")
    elif isinstance(animal, Cow):
        print("Moo")
    else:
        raise ValueError("animal doesn't know how to greet")

sayHi(Dog())
sayHi(Cat())
sayHi(Cow())
###############################################


where there are explicit type tests.  The decision-making here, the
flow of control, is explicit in the structure of the sayHi() function.


Now compare that versus the following:

###############################################
class Dog(object):
    def getGreeting(self): return "Woof"

class Cat(object):
    def getGreeting(self): return "Meow"

class Cow(object):
    def getGreeting(self): return "Moo"

def sayHi(animal):
    print(animal.getGreeting())

sayHi(Dog())
sayHi(Cat())
sayHi(Cow())
###############################################

You should see similar behavior.

But the control flow here is more implicit: it's not all apparent from
the structure of sayHi(): sayHi() looks like straight-line code.  The
decision-making hides in the type of the animal.  The flow of control
jumps from sayHi() to the getGreeting() of the particular animal, and
then finally back to sayHi() to do the printing of the greeting.


One of the values of this latter approach is that it's easier to add
more animals without having to rewrite sayHi().  For example, we can
introduce a Crow:

################################
class Crow(object):
    def getGreeting(self): return "Kaaa"

sayHi(Crow())
################################

and sayHi() can deal with it just fine.  In the first approach with
the explicit type tests, we'd have to modify sayHi() to let it handle
Crows.

From dyoo at hashcollision.org  Sun Jan  5 04:30:44 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 4 Jan 2014 19:30:44 -0800
Subject: [Tutor] python, speed, game programming
In-Reply-To: <20140104121516.GX29356@ando>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
 <la7neq$mbl$1@ger.gmane.org>
 <CAO5ffbZKBUWmaQmDcA7QeHmpRLKpezOdP995tjtiYpR=wDJiVA@mail.gmail.com>
 <20140104121516.GX29356@ando>
Message-ID: <CAGZAPF6Kd3DUA5s8a4HhXU2+nZhshuoyG9htJrFb458vc4W38w@mail.gmail.com>

There's an assumption in the question here that all programs are CPU bound.

I actually do not think so.  From prior discussion about what the
program is doing, I got the impression that it was trying to hold
gigabytes of data in RAM.  Isn't that still true?  If so, then I would
be very surprised if the program were not thrashing virtual memory.
Under such conditions, give up on any assumptions about program speed
being related to CPU speed.  It's hitting disk hard, and that's a Game
Over.  Under heavy virtual memory swapping conditions, it doesn't
matter how fast your CPU is: the time that your program is taking is
due to the physical act of moving spindles and spinning disks of metal
around.

From akleider at sonic.net  Sun Jan  5 05:16:10 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sat, 04 Jan 2014 20:16:10 -0800
Subject: [Tutor] encoding question
In-Reply-To: <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
Message-ID: <ace7aa764d02040486ab441f98b49c11@sonic.net>

On 2014-01-04 18:44, Danny Yoo wrote:
> Hi Alex,
> 
> 
> According to:
> 
>     http://www.hostip.info/use.html
> 
> there is a JSON-based interface.  I'd recommend using that one!  JSON
> is a format that's easy for machines to decode.  The format you're
> parsing is primarily for humans, and who knows if that will change in
> the future to make it easier to read?
> 
> Not only is JSON probably more reliable to parse, but the code itself
> should be fairly straightforward.  For example:
> 
> #########################################################
> ## In Python 2.7
> ##
>>>> import json
>>>> import urllib
>>>> response = urllib.urlopen('http://api.hostip.info/get_json.php')
>>>> info = json.load(response)
>>>> info
> {u'country_name': u'UNITED STATES', u'city': u'Mountain View, CA',
> u'country_code': u'US', u'ip': u'216.239.45.81'}
> #########################################################
> 
> 

This strikes me as being the most elegant solution to date, and I thank 
you for it!

The problem is that the city name doesn't come in:

alex at x301:~/Python/Parse$ cat tutor.py
#!/usr/bin/env python
# -*- coding : utf -8 -*-
# file: 'tutor.py'
"""
Put your docstring here.
"""
print "Running 'tutor.py'......."

import json
import urllib
response = urllib.urlopen\
  ('http://api.hostip.info/get_json.php?ip=201.234.178.62&position=true')
info = json.load(response)
print info

alex at x301:~/Python/Parse$ ./tutor.py
Running 'tutor.py'.......
{u'city': None, u'ip': u'201.234.178.62', u'lat': u'10.4', 
u'country_code': u'CO', u'country_name': u'COLOMBIA', u'lng': 
u'-75.2833'}

If I use my own IP the city comes in fine so there must still be some 
problem with the encoding.
should I be using
encoding = response.headers.getparam('charset')
in there somewhere?



Any ideas?

From eryksun at gmail.com  Sun Jan  5 05:47:53 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 4 Jan 2014 23:47:53 -0500
Subject: [Tutor] encoding question
In-Reply-To: <ace7aa764d02040486ab441f98b49c11@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando>
 <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando>
 <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
Message-ID: <CACL+1asgd8XTsyN49-RW=2irOoaGW+wy1z8F42o6WqzbR91RRg@mail.gmail.com>

On Sat, Jan 4, 2014 at 11:16 PM, Alex Kleider <akleider at sonic.net> wrote:
> {u'city': None, u'ip': u'201.234.178.62', u'lat': u'10.4', u'country_code':
> u'CO', u'country_name': u'COLOMBIA', u'lng': u'-75.2833'}
>
> If I use my own IP the city comes in fine so there must still be some
> problem with the encoding.

Report a bug in their JSON API. It's returning b'"city":null'. I see
the same problem for www.msj.go.cr in San Jos?, Costa Rica. It's
probably broken for all non-ASCII byte strings.

From dyoo at hashcollision.org  Sun Jan  5 06:20:10 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 4 Jan 2014 21:20:10 -0800
Subject: [Tutor] encoding question
In-Reply-To: <ace7aa764d02040486ab441f98b49c11@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando>
 <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando>
 <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
Message-ID: <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>

Oh!  That's unfortunate!  That looks like a bug on the hostip.info
side.  Check with them about it.


I can't get the source code to whatever is implementing the JSON
response, so I can not say why the city is not being properly included
there.


[... XML rant about to start.  I am not disinterested, so my apologies
in advance.]

... In that case... I suppose trying the XML output is a possible
approach.  But I truly dislike XML for being implemented in ways that
are usually not fun to navigate: either the APIs or the encoded data
are usually convoluted enough to make it a chore rather than a
pleasure.

The beginning does look similar:

##############################################################
>>> import xml.etree.ElementTree as ET
>>> import urllib
>>> response = urllib.urlopen("http://api.hostip.info?ip=201.234.178.62&position=true")
>>> tree = ET.parse(response)
>>> tree
<xml.etree.ElementTree.ElementTree object at 0x185a2d0>
##############################################################


Up to this point, not so bad.  But this is where it starts to look silly:

##############################################################
>>> tree.find('{http://www.opengis.net/gml}featureMember/Hostip/ip').text
'201.234.178.62'
>>> tree.find('{http://www.opengis.net/gml}featureMember/Hostip/{http://www.opengis.net/gml}name').text
u'Bogot\xe1'
##############################################################

where we need to deal with XML namespaces, an extra complexity for a
benefit that I have never bought into.


More than that, usually the XML I run into in practice isn't even
properly structured, as is the case with the lat-long value in the XML
output here:

##############################################################
>>> tree.find('.//{http://www.opengis.net/gml}coordinates').text
'-75.2833,10.4'
##############################################################

which is truly silly.  Why is the latitude and longitude not two
separate, structured values?  What is this XML buying us here, really
then?  I'm convinced that all the extraneous structure and complexity
in XML causes the people who work with it to stop caring, the result
being something that isn't for the benefit of either humans nor
computer programs.


Hence, that's why I prefer JSON: JSON export is usually a lot more
sensible, for reasons that I can speculate on, but I probably should
stop this rant.  :P

From keithwins at gmail.com  Sun Jan  5 06:32:01 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 5 Jan 2014 00:32:01 -0500
Subject: [Tutor] python, speed, game programming
In-Reply-To: <CAGZAPF6Kd3DUA5s8a4HhXU2+nZhshuoyG9htJrFb458vc4W38w@mail.gmail.com>
References: <CAO5ffbZfffvzTtMYqJhzK2qW6o9HuN3pMfMoX0RPOTtwUoywRg@mail.gmail.com>
 <CAO5ffbY8nd2AbRba2xOZKJFfhXwYh5oUUtkiuqkCNdym=ndpaQ@mail.gmail.com>
 <la7neq$mbl$1@ger.gmane.org>
 <CAO5ffbZKBUWmaQmDcA7QeHmpRLKpezOdP995tjtiYpR=wDJiVA@mail.gmail.com>
 <20140104121516.GX29356@ando>
 <CAGZAPF6Kd3DUA5s8a4HhXU2+nZhshuoyG9htJrFb458vc4W38w@mail.gmail.com>
Message-ID: <CAO5ffbZw7UB3WbqvaGewiPoau1BRiCEOyzZHDsoVOCCQYv_6Og@mail.gmail.com>

Hi Danny, no, I don't think there's any disk access, and the memory of the
two machines is rather different: one is 4 Gb or so, the other 9 changing
to 12 any day... but I think I haven't been rigorous enough to justify a
great deal more attention here. I am convinced that I should just keep
developing my next project, and my programming skills, and worry about
speed issues as I hit them. I was overreaching, or anticipating or
something...


On Sat, Jan 4, 2014 at 10:30 PM, Danny Yoo <dyoo at hashcollision.org> wrote:

> There's an assumption in the question here that all programs are CPU bound.
>
> I actually do not think so.  From prior discussion about what the
> program is doing, I got the impression that it was trying to hold
> gigabytes of data in RAM.  Isn't that still true?  If so, then I would
> be very surprised if the program were not thrashing virtual memory.
> Under such conditions, give up on any assumptions about program speed
> being related to CPU speed.  It's hitting disk hard, and that's a Game
> Over.  Under heavy virtual memory swapping conditions, it doesn't
> matter how fast your CPU is: the time that your program is taking is
> due to the physical act of moving spindles and spinning disks of metal
> around.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140105/b53d7c5a/attachment.html>

From dyoo at hashcollision.org  Sun Jan  5 07:11:03 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 4 Jan 2014 22:11:03 -0800
Subject: [Tutor] encoding question
In-Reply-To: <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando>
 <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando>
 <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
 <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
Message-ID: <CAGZAPF6gMGLLiyrcdJe2QfarswR75hx08+zvO2tZdOw10m4J+Q@mail.gmail.com>

> then?  I'm convinced that all the extraneous structure and complexity
> in XML causes the people who work with it to stop caring, the result
> being something that isn't for the benefit of either humans nor
> computer programs.


... I'm sorry.  Sometimes I get grumpy when I haven't had a Snickers.

I should not have said the above here.  It isn't factual, and worse,
it insinuates an uncharitable intent to people who I do not know.
There's enough insinuation and insults out there in the world already:
I should not be contributing to those things.  For that, I apologize.

From akleider at sonic.net  Sun Jan  5 07:32:27 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sat, 04 Jan 2014 22:32:27 -0800
Subject: [Tutor] encoding question
In-Reply-To: <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
 <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
Message-ID: <6bad5f93e22137c58a4385fcb4f85947@sonic.net>

On 2014-01-04 21:20, Danny Yoo wrote:
> Oh!  That's unfortunate!  That looks like a bug on the hostip.info
> side.  Check with them about it.
> 
> 
> I can't get the source code to whatever is implementing the JSON
> response, so I can not say why the city is not being properly included
> there.
> 
> 
> [... XML rant about to start.  I am not disinterested, so my apologies
> in advance.]
> 
> ... In that case... I suppose trying the XML output is a possible
> approach.  But I truly dislike XML for being implemented in ways that
> are usually not fun to navigate: either the APIs or the encoded data
> are usually convoluted enough to make it a chore rather than a
> pleasure.
> 
> The beginning does look similar:
> 
> ##############################################################
>>>> import xml.etree.ElementTree as ET
>>>> import urllib
>>>> response = 
>>>> urllib.urlopen("http://api.hostip.info?ip=201.234.178.62&position=true")
>>>> tree = ET.parse(response)
>>>> tree
> <xml.etree.ElementTree.ElementTree object at 0x185a2d0>
> ##############################################################
> 
> 
> Up to this point, not so bad.  But this is where it starts to look 
> silly:
> 
> ##############################################################
>>>> tree.find('{http://www.opengis.net/gml}featureMember/Hostip/ip').text
> '201.234.178.62'
>>>> tree.find('{http://www.opengis.net/gml}featureMember/Hostip/{http://www.opengis.net/gml}name').text
> u'Bogot\xe1'
> ##############################################################
> 
> where we need to deal with XML namespaces, an extra complexity for a
> benefit that I have never bought into.
> 
> 
> More than that, usually the XML I run into in practice isn't even
> properly structured, as is the case with the lat-long value in the XML
> output here:
> 
> ##############################################################
>>>> tree.find('.//{http://www.opengis.net/gml}coordinates').text
> '-75.2833,10.4'
> ##############################################################
> 
> which is truly silly.  Why is the latitude and longitude not two
> separate, structured values?  What is this XML buying us here, really
> then?  I'm convinced that all the extraneous structure and complexity
> in XML causes the people who work with it to stop caring, the result
> being something that isn't for the benefit of either humans nor
> computer programs.
> 
> 
> Hence, that's why I prefer JSON: JSON export is usually a lot more
> sensible, for reasons that I can speculate on, but I probably should
> stop this rant.  :P

Not a rant at all.

As it turns out, one of the other things that have interested me of late 
is docbook, an xml dialect (I think this is the correct way to express 
it.)  I've found it very useful and so do not share your distaste for 
xml although one can't disagree with the points you've made with regard 
to xml as a solution to the problem under discussion.
I've not played with the python xml interfaces before so this will be a 
good project for me.

Thanks.

From keithwins at gmail.com  Sun Jan  5 08:09:59 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 5 Jan 2014 02:09:59 -0500
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <52C80BE4.3000305@gmail.com>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
 <52C7DD5D.6000700@gmail.com>
 <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>
 <52C7F57D.4060600@gmail.com>
 <CAO5ffbaNu2vpjm5KKUx20KN+vpbe_fjqE4pP6g1B1fo_6tE6ow@mail.gmail.com>
 <20140104130324.GY29356@ando> <52C80BE4.3000305@gmail.com>
Message-ID: <CAO5ffbaWhjM1kT__AeaJDuMtarpDJwTGDJxusibtu-S2TzW-fg@mail.gmail.com>

Thanks all, interesting. I'll play more with tuples, I haven't knowingly
used them at all...

Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140105/a880d24e/attachment.html>

From breamoreboy at yahoo.co.uk  Sun Jan  5 08:52:52 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 05 Jan 2014 07:52:52 +0000
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <CAO5ffbaWhjM1kT__AeaJDuMtarpDJwTGDJxusibtu-S2TzW-fg@mail.gmail.com>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
 <52C7DD5D.6000700@gmail.com>
 <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>
 <52C7F57D.4060600@gmail.com>
 <CAO5ffbaNu2vpjm5KKUx20KN+vpbe_fjqE4pP6g1B1fo_6tE6ow@mail.gmail.com>
 <20140104130324.GY29356@ando> <52C80BE4.3000305@gmail.com>
 <CAO5ffbaWhjM1kT__AeaJDuMtarpDJwTGDJxusibtu-S2TzW-fg@mail.gmail.com>
Message-ID: <lab2vt$oin$1@ger.gmane.org>

On 05/01/2014 07:09, Keith Winston wrote:
>
> Thanks all, interesting. I'll play more with tuples, I haven't knowingly
> used them at all...
>
> Keith
>

Homework for you :)  Write a line of code that creates a list of say 3 
or 4 integers, then write a line that creates a tuple with the same 
integers.  Use the dis module to compare the byte code that the two 
lines of code produce.  The difference is interesting.

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

Mark Lawrence


From akleider at sonic.net  Sun Jan  5 08:57:20 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sat, 04 Jan 2014 23:57:20 -0800
Subject: [Tutor] encoding question
In-Reply-To: <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
 <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
Message-ID: <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net>

On 2014-01-04 21:20, Danny Yoo wrote:
> Oh!  That's unfortunate!  That looks like a bug on the hostip.info
> side.  Check with them about it.
> 
> 
> I can't get the source code to whatever is implementing the JSON
> response, so I can not say why the city is not being properly included
> there.
> 
> 
> [... XML rant about to start.  I am not disinterested, so my apologies
> in advance.]
> 
> ... In that case... I suppose trying the XML output is a possible
> approach.

Well, I've tried the xml approach which seems promising but still I get 
an encoding related error.
Is there a bug in the xml.etree module (not very likely, me thinks) or 
am I doing something wrong?
There's no denying that the whole encoding issue is still not completely 
clear to me in spite of having devoted a lot of time to trying to grasp 
all that's involved.

Here's what I've got:

alex at x301:~/Python/Parse$ cat ip_xml.py
#!/usr/bin/env python
# -*- coding : utf -8 -*-
# file: 'ip_xml.py'

import urllib2
import xml.etree.ElementTree as ET


url_format_str = \
     u'http://api.hostip.info/?ip=%s&position=true'

def ip_info(ip_address):
     response =  urllib2.urlopen(url_format_str %\
                                    (ip_address, ))
     encoding = response.headers.getparam('charset')
     print "'encoding' is '%s'." % (encoding, )
     info = unicode(response.read().decode(encoding))
     n = info.find('\n')
     print "location of first newline is %s." % (n, )
     xml = info[n+1:]
     print "'xml' is '%s'." % (xml, )

     tree = ET.fromstring(xml)
     root = tree.getroot()   # Here's where it blows up!!!
     print "'root' is '%s', with the following children:" % (root, )
     for child in root:
         print child.tag, child.attrib
     print "END of CHILDREN"
     return info

if __name__ == "__main__":
     info = ip_info("201.234.178.62")

alex at x301:~/Python/Parse$ ./ip_xml.py
'encoding' is 'iso-8859-1'.
location of first newline is 44.
'xml' is '<HostipLookupResultSet version="1.0.1" 
xmlns:gml="http://www.opengis.net/gml" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="http://www.hostip.info/api/hostip-1.0.1.xsd">
  <gml:description>This is the Hostip Lookup Service</gml:description>
  <gml:name>hostip</gml:name>
  <gml:boundedBy>
   <gml:Null>inapplicable</gml:Null>
  </gml:boundedBy>
  <gml:featureMember>
   <Hostip>
    <ip>201.234.178.62</ip>
    <gml:name>Bogot?</gml:name>
    <countryName>COLOMBIA</countryName>
    <countryAbbrev>CO</countryAbbrev>
    <!-- Co-ordinates are available as lng,lat -->
    <ipLocation>
     <gml:pointProperty>
      <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
       <gml:coordinates>-75.2833,10.4</gml:coordinates>
      </gml:Point>
     </gml:pointProperty>
    </ipLocation>
   </Hostip>
  </gml:featureMember>
</HostipLookupResultSet>
'.
Traceback (most recent call last):
   File "./ip_xml.py", line 33, in <module>
     info = ip_info("201.234.178.62")
   File "./ip_xml.py", line 23, in ip_info
     tree = ET.fromstring(xml)
   File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1301, in XML
     parser.feed(text)
   File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1641, in feed
     self._parser.Parse(data, 0)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in 
position 456: ordinal not in range(128)




From denis.spir at gmail.com  Sun Jan  5 10:11:05 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 05 Jan 2014 10:11:05 +0100
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <lab2vt$oin$1@ger.gmane.org>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
 <52C7DD5D.6000700@gmail.com>
 <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>
 <52C7F57D.4060600@gmail.com>
 <CAO5ffbaNu2vpjm5KKUx20KN+vpbe_fjqE4pP6g1B1fo_6tE6ow@mail.gmail.com>
 <20140104130324.GY29356@ando> <52C80BE4.3000305@gmail.com>
 <CAO5ffbaWhjM1kT__AeaJDuMtarpDJwTGDJxusibtu-S2TzW-fg@mail.gmail.com>
 <lab2vt$oin$1@ger.gmane.org>
Message-ID: <52C921A9.70704@gmail.com>

On 01/05/2014 08:52 AM, Mark Lawrence wrote:
> On 05/01/2014 07:09, Keith Winston wrote:
>>
>> Thanks all, interesting. I'll play more with tuples, I haven't knowingly
>> used them at all...
>>
>> Keith
>>
>
> Homework for you :)  Write a line of code that creates a list of say 3 or 4
> integers, then write a line that creates a tuple with the same integers.  Use
> the dis module to compare the byte code that the two lines of code produce.  The
> difference is interesting.

Interesting indeed. Thanks Mark, for the suggestion :-)
denis

From amrita.g13 at gmail.com  Sun Jan  5 03:01:16 2014
From: amrita.g13 at gmail.com (Amrita Kumari)
Date: Sun, 5 Jan 2014 10:01:16 +0800
Subject: [Tutor] Fwd:  arrangement of datafile
In-Reply-To: <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
Message-ID: <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>

Sorry I forgot to add tutor mailing list.....please help for the below.

---------- Forwarded message ----------
From: Amrita Kumari <amrita.g13 at gmail.com>
Date: Fri, Jan 3, 2014 at 2:42 PM
Subject: Re: [Tutor] arrangement of datafile
To: Evans Anyokwu <onyxtic at gmail.com>


Hi,

I have saved my data in csv format now it is looking like this:

2,ALA,C=178.255,CA=53.263,CB=18.411,,,,,,,,,,
3,LYS,H=8.607,C=176.752,CA=57.816,CB=31.751,N=119.081,,,,,,,,
4,ASN,H=8.185,C=176.029,CA=54.712,CB=38.244,N=118.255,,,,,,,,
5,VAL,H=7.857,HG11=0.892,HG12=0.892,HG13=0.892,HG21=0.954,HG22=0.954,HG23=0.954,C=177.259,CA=64.232,CB=31.524,CG1=21.402,CG2=21.677,N=119.998
6,ILE,H=8.062,HG21=0.827,HG22=0.827,HG23=0.827,HD11=0.807,HD12=0.807,HD13=0.807,C=177.009,CA=63.400,CB=37.177,CG2=17.565,CD1=13.294,N=122.474
7,VAL,H=7.993,HG11=0.879,HG12=0.879,HG13=0.879,HG21=0.957,HG22=0.957,HG23=0.957,C=177.009,CA=65.017,CB=31.309,CG1=21.555,CG2=22.369,N=120.915
8,LEU,H=8.061,HD11=0.844,HD12=0.844,HD13=0.844,HD21=0.810,HD22=0.810,HD23=0.810,C=178.655,CA=56.781,CB=41.010,CD1=25.018,CD2=23.824,N=121.098
9,ASN,H=8.102,C=176.695,CA=54.919,CB=38.674,N=118.347,,,,,,,,
10,ALA,H=8.388,HB1=1.389,HB2=1.389,HB3=1.389,C=178.263,CA=54.505,CB=17.942,N=124.124,,,,,
11,ALA,H=8.279,HB1=1.382,HB2=1.382,HB3=1.382,C=179.204,CA=54.298,CB=17.942,N=119.814,,,,,
12,SER,H=7.952,C=175.873,CA=60.140,CB=63.221,N=113.303,,,,,,,,
13,ALA,H=7.924,HB1=1.382,HB2=1.382,HB3=1.382,C=178.420,CA=53.470,CB=18.373,N=124.308,,,,,
------------------
---------------------
-------------------

with comma seperated:

I can read the file as

infile = open('inputfile.csv', 'r')

I can read each line through

data = infile.readlines()

I can split the line into a list of strings at comma occurences as

for line in data:
          csvline = line.strip().split(",")

after this please help me to guide how to proceed as I am new in
programming but want to learn python program.

Thanks,
Amrita


On 12/28/13, Evans Anyokwu <onyxtic at gmail.com> wrote:
> One thing that I've noticed is that there is no structure to your data.
> Some have missing *fields* -so making the use of regex out of the
question.
>
> Without seeing your code, I'd suggest saving the data as a separated value
> file and parse it. Python has a good csv support.
>
> Get this one sorted out first then we can move on to the nested list.
>
> Good luck.
> Evans
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140105/7bef0b2c/attachment.html>

From denis.spir at gmail.com  Sun Jan  5 10:51:54 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 05 Jan 2014 10:51:54 +0100
Subject: [Tutor] encoding question
In-Reply-To: <20140104235243.GA29356@ando>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando>
Message-ID: <52C92B3A.30804@gmail.com>

On 01/05/2014 12:52 AM, Steven D'Aprano wrote:
> If you don't understand an exception, you
> have no business covering it up and hiding that it took place. Never use
> a bare try...except, always catch the *smallest* number of specific
> exception types that make sense. Better is to avoid catching exceptions
> at all: an exception (usually) means something has gone wrong. You
> should aim to fix the problem *before* it blows up, not after.
>
> I'm reminded of a quote:
>
> "I find it amusing when novice programmers believe their main job is
> preventing programs from crashing. ... More experienced programmers
> realize that correct code is great, code that crashes could use
> improvement, but incorrect code that doesn't crash is a horrible
> nightmare." -- Chris Smith
>
> Your code is incorrect, it does the wrong thing, but it doesn't crash,
> it just covers up the fact that an exception occured.

An exception, or any other kind of anomaly detected by a func one calls, is in 
most cases a *symptom* of an error, somewhere else in one's code (possibly far 
in source, possibly long earlier, possibly apparently unrelated). Catching an 
exception (except in rare cases), is just suppressing a _signal_ about a 
probable error. Catching an exception does not make the code correct, it just 
pretends to (except in rare cases). It's like hiding the dirt under a carpet, or 
beating up the poor guy that ran for 3 kilometers to tell you a fire in 
threatening your home.

Again: the anomaly (eg wrong input) detected by a func is not the error; it is a 
consequence of the true original error, what one should aim at correcting. (But 
our culture apparently loves repressing symptoms rather than curing actual 
problems: we programmers just often thoughtlessly apply the scheme ;-)

We should instead gratefully thank func authors for having correctly done their 
jobs of controlling input. They offer us the information needed to find bugs 
which otherwise may happily go on their lives undetected; and thus the 
opportunity to write more correct software. (This is why func authors should 
control input, refuse any anomalous or dubious values, and never ever try to 
guess what the app expects in such cases; instead just say "cannot do my job 
safely, or at all".)

If one is passing an empty set to an 'average' func, don't blame the func or 
shut up the signal/exception, instead be grateful to the func's author, and find 
why and how it happens the set is empty. If one is is trying to write into a 
file, don't blame the file for not existing, the user for being stupid, or shut 
up the signal/exception, instead be grateful to the func's author, and find why 
and how it happens the file does not exist, now (about the user: is your doc 
clear enough?).

The sub-category of cases where exception handling makes sense at all is the 
following:
* a called function may fail (eg average, find a given item in a list, write 
into a file)
* and, the failure case makes sense for the app, it _does_ belong to the app logic
* and, the case should nevertheless be handled like others up to this point in 
code (meaning, there should not be a separate branch for it, we should really 
land there in code even for this failure case)
* and, one cannot know whether it is a failure case without trying, or it would 
be as costly as just trying (wrong for average, right for 2 other examples)
* and, one can repair the failure right here, in any case, and go on correctly 
according to the app logic (depends on apps) (there is also the category of 
alternate running modes)

In such a situation, the right thing to do is to catch the exception signal (or 
use whatever error management exists, eg a check for a None return value) and 
proceed correctly (and think at testing this case ;-).

But this is not that common. In particular, if the failure case does not belong 
to the app logic (the item should be there, the file should exist) then do *not* 
catch a potential signal: if it happens, it would tell you about a bug 
*elsewhere* in code; and _this_ is what is to correct.

There a mythology in programming, that software should not crash; wrongly 
understood (or rightly, authors of such texts usually are pretty unclear and 
ambiguous), this leads to catching exceptions that are just signal of symptoms 
of errors... Instead, software should crash whenever it is incorrect; often 
(when the error does not cause obvious misbehaviour) it is the only way for the 
programmer to know about errors. Crashes are the programmer's best friend (I 
mean, those programmers which aim is to write quality software).

Denis

From denis.spir at gmail.com  Sun Jan  5 10:55:51 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 05 Jan 2014 10:55:51 +0100
Subject: [Tutor] encoding question
In-Reply-To: <0f67356033ea2385876180615faf3ea3@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
Message-ID: <52C92C27.6050006@gmail.com>

On 01/04/2014 08:26 PM, Alex Kleider wrote:
> Any suggestions as to a better way to handle the problem of encoding in the
> following context would be appreciated.  The problem arose because 'Bogota' is
> spelt with an acute accent on the 'a'.
>
> $ cat IP_info.py3
> #!/usr/bin/env python3
> # -*- coding : utf -8 -*-
> # file: 'IP_info.py3'  a module.
>
> import urllib.request
>
> url_format_str = \
>      'http://api.hostip.info/get_html.php?ip=%s&position=true'
>
> def ip_info(ip_address):
>      """
> Returns a dictionary keyed by Country, City, Lat, Long and IP.
>
> Depends on http://api.hostip.info (which returns the following:
> 'Country: UNITED STATES (US)\nCity: Santa Rosa, CA\n\nLatitude:
> 38.4486\nLongitude: -122.701\nIP: 76.191.204.54\n'.)
> THIS COULD BREAK IF THE WEB SITE GOES AWAY!!!
> """
>      response =  urllib.request.urlopen(url_format_str %\
>                                     (ip_address, )).read()
>      sp = response.splitlines()
>      country = city = lat = lon = ip = ''
>      for item in sp:
>          if item.startswith(b"Country:"):
>              try:
>                  country = item[9:].decode('utf-8')
>              except:
>                  print("Exception raised.")
>                  country = item[9:]
>          elif item.startswith(b"City:"):
>              try:
>                  city = item[6:].decode('utf-8')
>              except:
>                  print("Exception raised.")
>                  city = item[6:]
>          elif item.startswith(b"Latitude:"):
>              try:
>                  lat = item[10:].decode('utf-8')
>              except:
>                  print("Exception raised.")
>                  lat = item[10]
>          elif item.startswith(b"Longitude:"):
>              try:
>                  lon = item[11:].decode('utf-8')
>              except:
>                  print("Exception raised.")
>                  lon = item[11]
>          elif item.startswith(b"IP:"):
>              try:
>                  ip = item[4:].decode('utf-8')
>              except:
>                  print("Exception raised.")
>                  ip = item[4:]
>      return {"Country" : country,
>              "City" : city,
>              "Lat" : lat,
>              "Long" : lon,
>              "IP" : ip            }
>
> if __name__ == "__main__":
>      addr =  "201.234.178.62"
>      print ("""    IP address is %(IP)s:
>          Country: %(Country)s;  City: %(City)s.
>          Lat/Long: %(Lat)s/%(Long)s""" % ip_info(addr))
> """
>
> The output I get on an Ubuntu 12.4LTS system is as follows:
> alex at x301:~/Python/Parse$ ./IP_info.py3
> Exception raised.
>      IP address is 201.234.178.62:
>          Country: COLOMBIA (CO);  City: b'Bogot\xe1'.
>          Lat/Long: 10.4/-75.2833
>
>
> I would have thought that utf-8 could handle the 'a-acute'.
>
> Thanks,
> alex

'?' does not encode to 0xe1 in utf8 encoding; what you read is probably (legacy) 
files in probably latin-1 (or another latin-* encoding).

Denis

From denis.spir at gmail.com  Sun Jan  5 11:06:34 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 05 Jan 2014 11:06:34 +0100
Subject: [Tutor] encoding question
In-Reply-To: <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
Message-ID: <52C92EAA.7040500@gmail.com>

On 01/05/2014 03:31 AM, Alex Kleider wrote:
> I've been maintaining both a Python3 and a Python2.7 version.  The latter has
> actually opened my eyes to more complexities. Specifically the need to use
> unicode strings rather than Python2.7's default ascii.

So-called Unicode strings are not the solution to all problems. Example with 
your '?', which can be represented by either 1 "precomposed" code (unicode code 
point) 0xe1, or ibasically by 2 ucodes (one for the "base" 'a', one for the 
"combining" '?'). Imagine you search for "Bogot?": how do you know which is 
reprsentation is used in the text you search? How do you know at all there are 
multiple representations, and what they are? The routine wil work iff, by 
chance, your *programming editor* (!) used the same representation as the 
software used to create the searched test...

Usually it the case, because most text-creation software use precomposed codes, 
when they exist, for composite characters. (But this fact just makes the issue 
more rare, hard to be aware of, and thus difficult to cope with correctly in 
code. As far as I know nearly no software does it.)

Denis

From denis.spir at gmail.com  Sun Jan  5 11:18:35 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 05 Jan 2014 11:18:35 +0100
Subject: [Tutor] encoding question
In-Reply-To: <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
 <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
 <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net>
Message-ID: <52C9317B.8050801@gmail.com>

On 01/05/2014 08:57 AM, Alex Kleider wrote:
> On 2014-01-04 21:20, Danny Yoo wrote:
>> Oh!  That's unfortunate!  That looks like a bug on the hostip.info
>> side.  Check with them about it.
>>
>>
>> I can't get the source code to whatever is implementing the JSON
>> response, so I can not say why the city is not being properly included
>> there.
>>
>>
>> [... XML rant about to start.  I am not disinterested, so my apologies
>> in advance.]
>>
>> ... In that case... I suppose trying the XML output is a possible
>> approach.
>
> Well, I've tried the xml approach which seems promising but still I get an
> encoding related error.
.org/mailman/listinfo/tutor

Note that the (computing) data description format (JSON, XML...) and the textual 
format, or "encoding" (Unicode utf8/16/32, legacy iso-8859-* also called 
latin-*, ...) are more or less unrelated and independant. Changing the data 
description format cannot solve a text encoding issue (but it may hide it, if by 
chance the new data description format happened to use the text encoding you 
happen to use when reading, implicitely or explicitely).

Denis

From breamoreboy at yahoo.co.uk  Sun Jan  5 11:31:17 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 05 Jan 2014 10:31:17 +0000
Subject: [Tutor] encoding question
In-Reply-To: <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
Message-ID: <labc8o$9kn$1@ger.gmane.org>

On 05/01/2014 02:31, Alex Kleider wrote:
>
> I've been maintaining both a Python3 and a Python2.7 version.  The
> latter has actually opened my eyes to more complexities. Specifically
> the need to use unicode strings rather than Python2.7's default ascii.
>

This might help http://python-future.org/

-- 
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  Sun Jan  5 11:55:38 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 5 Jan 2014 21:55:38 +1100
Subject: [Tutor] encoding question
In-Reply-To: <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
 <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
 <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net>
Message-ID: <20140105105536.GE29356@ando>

On Sat, Jan 04, 2014 at 11:57:20PM -0800, Alex Kleider wrote:

> Well, I've tried the xml approach which seems promising but still I get 
> an encoding related error.
> Is there a bug in the xml.etree module (not very likely, me thinks) or 
> am I doing something wrong?

I'm no expert on XML, but it looks to me like it is a bug in 
ElementTree. It doesn't appear to handle unicode strings correctly 
(although perhaps it doesn't promise to).

A simple demonstration using Python 2.7:

py> import xml.etree.ElementTree as ET
py> ET.fromstring(u'<xml>a</xml>')
<Element 'xml' at 0xb7ca982c>

But:

py> ET.fromstring(u'<xml>?</xml>')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/xml/etree/ElementTree.py", line 1282, in XML
    parser.feed(text)
  File "/usr/local/lib/python2.7/xml/etree/ElementTree.py", line 1622, in feed
    self._parser.Parse(data, 0)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in 
position 5: ordinal not in range(128)

An easy work-around:

py> ET.fromstring(u'<xml>?</xml>'.encode('utf-8'))
<Element 'xml' at 0xb7ca9a8c>

although, as I said, I'm no expert on XML and this may lead to errors 
later on.


> There's no denying that the whole encoding issue is still not completely 
> clear to me in spite of having devoted a lot of time to trying to grasp 
> all that's involved.

Have you read Joel On Software's explanation?

http://www.joelonsoftware.com/articles/Unicode.html

It's well worth reading. Start with that, and then ask if you have any 
further questions.


> Here's what I've got:
> 
> alex at x301:~/Python/Parse$ cat ip_xml.py
> #!/usr/bin/env python
> # -*- coding : utf -8 -*-
> # file: 'ip_xml.py'
[...]
>     tree = ET.fromstring(xml)
>     root = tree.getroot()   # Here's where it blows up!!!

I reckon that what you need is to change the first line to:

    tree = ET.fromstring(xml.encode('latin-1'))

or whatever the encoding is meant to be.


-- 
Steven

From jjk.saji at gmail.com  Sun Jan  5 13:38:07 2014
From: jjk.saji at gmail.com (Joseph John)
Date: Sun, 5 Jan 2014 16:38:07 +0400
Subject: [Tutor] Finding the latest file in a dir
Message-ID: <CAKeuxjA=dEHMtyZjeh0k1oh+gJz1JaotSoA4BkVGXgev4p0WCg@mail.gmail.com>

Hi All,
Even though I am a old user in the mailing list, my skills in Python are
not impressive.
I have restarted doing python for some small task.
I am trying to find the latest file in a dir, I have searched and found out
I shoulld do in this way
----------------
#!/usr/bin/python

import os
newest = max(os.listdir("/opt/AlfDB/."), key = os.path.getctime)
print newest
-----------------------
but when I run it I am getting error message such as
./FindingLatestFileInDir.py
Traceback (most recent call last):
  File "./FindingLatestFileInDir.py", line 4, in <module>
    newest = max(os.listdir("/opt/AlfDB/."), key = os.path.getctime)
  File "/usr/lib64/python2.7/genericpath.py", line 64, in getctime
    return os.stat(filename).st_ctime
OSError: [Errno 2] No such file or directory: 'alfresco20140104-0000.sql'

------------------------------------------------------
I get results if I do it without giving the dir location such as
---
#!/usr/bin/python

import os
newest = max(os.listdir("."), key = os.path.getctime)
print newest
---------------------
This gives the result for the directory from where it runs, but when I
change the dir location to "/opt/AlfDB" , It does not. I am not able to
apprehend how it is not working

Guidance and advice requested
Thanks
Joseph John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140105/3cac4997/attachment.html>

From nik at naturalnet.de  Sun Jan  5 13:45:25 2014
From: nik at naturalnet.de (Dominik George)
Date: Sun, 5 Jan 2014 13:45:25 +0100
Subject: [Tutor] Finding the latest file in a dir
In-Reply-To: <CAKeuxjA=dEHMtyZjeh0k1oh+gJz1JaotSoA4BkVGXgev4p0WCg@mail.gmail.com>
References: <CAKeuxjA=dEHMtyZjeh0k1oh+gJz1JaotSoA4BkVGXgev4p0WCg@mail.gmail.com>
Message-ID: <20140105124524.GE5140@keks.naturalnet.de>

Hi,

> OSError: [Errno 2] No such file or directory: 'alfresco20140104-0000.sql'

> I get results if I do it without giving the dir location such as

That is because the getctime call will run based in the current working
directory. You can use a construct like:

  max([os.path.join('opt', 'foo', x) for x in os.listdir(os.path.join('opt', 'foo')], key=os.path.getctime)

That uses a list comprehension to prepend the full path to the results.
You could also chdir() to the location beforehand.

Please always use os.path.join().

-nik

-- 
<Natureshadow> Auf welchem Server liegt das denn jetzt??
<mirabilos> Wenn es nicht ?bers Netz kommt bei Hetzner, wenn es nicht
            gelesen wird bei STRATO, wenn es klappt bei manitu.

PGP-Fingerprint: 3C9D 54A4 7575 C026 FB17  FD26 B79A 3C16 A0C4 F296
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 905 bytes
Desc: Digital signature
URL: <http://mail.python.org/pipermail/tutor/attachments/20140105/495cb05a/attachment.sig>

From eryksun at gmail.com  Sun Jan  5 17:02:34 2014
From: eryksun at gmail.com (eryksun)
Date: Sun, 5 Jan 2014 11:02:34 -0500
Subject: [Tutor] encoding question
In-Reply-To: <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando>
 <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando>
 <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
 <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
 <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net>
Message-ID: <CACL+1auwfODNqPZfH5aDtAgcO6mJcODqf8JbbDzjxYyuikYbxQ@mail.gmail.com>

On Sun, Jan 5, 2014 at 2:57 AM, Alex Kleider <akleider at sonic.net> wrote:
> def ip_info(ip_address):
>
>     response =  urllib2.urlopen(url_format_str %\
>                                    (ip_address, ))
>     encoding = response.headers.getparam('charset')
>     print "'encoding' is '%s'." % (encoding, )
>     info = unicode(response.read().decode(encoding))

decode() returns a unicode object.

>     n = info.find('\n')
>     print "location of first newline is %s." % (n, )
>     xml = info[n+1:]
>     print "'xml' is '%s'." % (xml, )
>
>     tree = ET.fromstring(xml)
>     root = tree.getroot()   # Here's where it blows up!!!
>     print "'root' is '%s', with the following children:" % (root, )
>     for child in root:
>         print child.tag, child.attrib
>     print "END of CHILDREN"
>     return info

Danny walked you through the XML. Note that he didn't decode the
response. It includes an encoding on the first line:

    <?xml version="1.0" encoding="ISO-8859-1" ?>

Leave it to ElementTree. Here's something to get you started:

    import urllib2
    import xml.etree.ElementTree as ET
    import collections

    url_format_str = 'http://api.hostip.info/?ip=%s&position=true'
    GML = 'http://www.opengis.net/gml'
    IPInfo = collections.namedtuple('IPInfo', '''
        ip
        city
        country
        latitude
        longitude
    ''')

    def ip_info(ip_address):
        response = urllib2.urlopen(url_format_str %
                                   ip_address)
        tree = ET.fromstring(response.read())
        hostip = tree.find('{%s}featureMember/Hostip' % GML)
        ip = hostip.find('ip').text
        city = hostip.find('{%s}name' % GML).text
        country = hostip.find('countryName').text
        coord = hostip.find('.//{%s}coordinates' % GML).text
        lon, lat = coord.split(',')
        return IPInfo(ip, city, country, lat, lon)


    >>> info = ip_info('201.234.178.62')
    >>> info.ip
    '201.234.178.62'
    >>> info.city, info.country
    (u'Bogot\xe1', 'COLOMBIA')
    >>> info.latitude, info.longitude
    ('10.4', '-75.2833')

This assumes everything works perfect. You have to decide how to fail
gracefully for the service being unavailable or malformed XML
(incomplete or corrupted response, etc).

From keithwins at gmail.com  Sun Jan  5 20:40:47 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 5 Jan 2014 14:40:47 -0500
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <lab2vt$oin$1@ger.gmane.org>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
 <52C7DD5D.6000700@gmail.com>
 <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>
 <52C7F57D.4060600@gmail.com>
 <CAO5ffbaNu2vpjm5KKUx20KN+vpbe_fjqE4pP6g1B1fo_6tE6ow@mail.gmail.com>
 <20140104130324.GY29356@ando> <52C80BE4.3000305@gmail.com>
 <CAO5ffbaWhjM1kT__AeaJDuMtarpDJwTGDJxusibtu-S2TzW-fg@mail.gmail.com>
 <lab2vt$oin$1@ger.gmane.org>
Message-ID: <CAO5ffbb7TjJ=_A3FZ+NX9q1XQRmxxmGTJRktut8Wrk0XPOF2ww@mail.gmail.com>

On Sun, Jan 5, 2014 at 2:52 AM, Mark Lawrence <breamoreboy at yahoo.co.uk>wrote:

> Homework for you :)  Write a line of code that creates a list of say 3 or
> 4 integers, then write a line that creates a tuple with the same integers.
>  Use the dis module to compare the byte code that the two lines of code
> produce.  The difference is interesting.



Well... that was a very interesting assignment, though I'm going to have to
chew on it for a while to understand. I can see that the processing code
for a tuple is considerably shorter... it is processed in a gulp instead of
bite by byte... it doesn't have the "Build List" step at all (what goes on
inside of THAT?)... but I can't claim to really understand what I'm looking
at.

I notice, for example, if I include only constants (immutable types) in my
tuple, then it does that gulp thing. If I include a list in there too, all
hell breaks loose, and suddenly I'm Building Tuples (what goes on inside of
THAT?). A tuple of tuples still goes down in a single swallow, of course.

Sadly, you can see how my mind works here... hey, this was FUN! You can
assign me homework any time, teach!

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140105/1087fe3f/attachment.html>

From keithwins at gmail.com  Sun Jan  5 21:01:43 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 5 Jan 2014 15:01:43 -0500
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
Message-ID: <CAO5ffbZMwioCL2VApAkD1Y7p05dMk8ji3b-Cpt=3WOHMAi+Ccw@mail.gmail.com>

Hi Amrita, I'm just a beginner but I notice that, after the first two
entries on each line (i.e. 10,ALA), the rest might fit nicely into a dict,
like this {H: 8.388, HB1: 1.389, ...}. That would give you a lot of
flexibility in getting at the values later. It would be easy enough to
replace the "=" with ':", and add some curly braces. In fact, if you
enclosed each line in square braces, changed =/: and added the curly braces
on the dict, then each line would already be a list containing a
dictionary, and you'd be ready to do some rearranging very easily.

Whether you do that in Python or when you are building your file in
whatever system it's coming from is your call. If you left off the outer
braces, each line is a tuple containing a dict, which works too.

Sorry if all I've done is state the obvious here. I warned you I'm a
beginner.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140105/3535bb8e/attachment-0001.html>

From akleider at sonic.net  Sun Jan  5 21:14:10 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sun, 05 Jan 2014 12:14:10 -0800
Subject: [Tutor] encoding question
In-Reply-To: <CACL+1auwfODNqPZfH5aDtAgcO6mJcODqf8JbbDzjxYyuikYbxQ@mail.gmail.com>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
 <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
 <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net>
 <CACL+1auwfODNqPZfH5aDtAgcO6mJcODqf8JbbDzjxYyuikYbxQ@mail.gmail.com>
Message-ID: <8c0134f6cefe1926cd21bb7061f095f5@sonic.net>

On 2014-01-05 08:02, eryksun wrote:
> On Sun, Jan 5, 2014 at 2:57 AM, Alex Kleider <akleider at sonic.net> 
> wrote:
>> def ip_info(ip_address):
>> 
>>     response =  urllib2.urlopen(url_format_str %\
>>                                    (ip_address, ))
>>     encoding = response.headers.getparam('charset')
>>     print "'encoding' is '%s'." % (encoding, )
>>     info = unicode(response.read().decode(encoding))
> 
> decode() returns a unicode object.
> 
>>     n = info.find('\n')
>>     print "location of first newline is %s." % (n, )
>>     xml = info[n+1:]
>>     print "'xml' is '%s'." % (xml, )
>> 
>>     tree = ET.fromstring(xml)
>>     root = tree.getroot()   # Here's where it blows up!!!
>>     print "'root' is '%s', with the following children:" % (root, )
>>     for child in root:
>>         print child.tag, child.attrib
>>     print "END of CHILDREN"
>>     return info
> 
> Danny walked you through the XML. Note that he didn't decode the
> response. It includes an encoding on the first line:
> 
>     <?xml version="1.0" encoding="ISO-8859-1" ?>
> 
> Leave it to ElementTree. Here's something to get you started:
> 
>     import urllib2
>     import xml.etree.ElementTree as ET
>     import collections
> 
>     url_format_str = 'http://api.hostip.info/?ip=%s&position=true'
>     GML = 'http://www.opengis.net/gml'
>     IPInfo = collections.namedtuple('IPInfo', '''
>         ip
>         city
>         country
>         latitude
>         longitude
>     ''')
> 
>     def ip_info(ip_address):
>         response = urllib2.urlopen(url_format_str %
>                                    ip_address)
>         tree = ET.fromstring(response.read())
>         hostip = tree.find('{%s}featureMember/Hostip' % GML)
>         ip = hostip.find('ip').text
>         city = hostip.find('{%s}name' % GML).text
>         country = hostip.find('countryName').text
>         coord = hostip.find('.//{%s}coordinates' % GML).text
>         lon, lat = coord.split(',')
>         return IPInfo(ip, city, country, lat, lon)
> 
> 
>     >>> info = ip_info('201.234.178.62')
>     >>> info.ip
>     '201.234.178.62'
>     >>> info.city, info.country
>     (u'Bogot\xe1', 'COLOMBIA')
>     >>> info.latitude, info.longitude
>     ('10.4', '-75.2833')
> 
> This assumes everything works perfect. You have to decide how to fail
> gracefully for the service being unavailable or malformed XML
> (incomplete or corrupted response, etc).

Thanks again for the input.
You're using some ET syntax there that would probably make my code much 
more readable but will require a bit more study on my part.

I was up all night trying to get this sorted out and was finally 
successful.
(Re-) Reading 'joelonsoftware' and some of the Python docs helped.
Here's what I came up with (still needs modification to return a 
dictionary, but that'll be trivial.)

alex at x301:~/Python/Parse$ cat ip_xml.py
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# -*- coding : utf-8 -*-
# file: 'ip_xml.py'

import urllib2
import xml.etree.ElementTree as ET


url_format_str = \
     u'http://api.hostip.info/?ip=%s&position=true'

def ip_info(ip_address):
     response =  urllib2.urlopen(url_format_str %\
                                    (ip_address, ))
     encoding = response.headers.getparam('charset')
     info = response.read().decode(encoding)
     # <info> comes in as <type 'unicode'>.
     n = info.find('\n')
     xml = info[n+1:]  # Get rid of a header line.
     # root = ET.fromstring(xml) # This causes error:
     # UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1'
     # in position 456: ordinal not in range(128)
     root = ET.fromstring(xml.encode("utf-8"))
     # This is the part I still don't fully understand but would
     # probably have to look at the library source to do so.
     info = []
     for i in range(4):
         info.append(root[3][0][i].text)
     info.append(root[3][0][4][0][0][0].text)

     return info

if __name__ == "__main__":
     info = ip_info("201.234.178.62")
     print info
     print info[1]

alex at x301:~/Python/Parse$ ./ip_xml.py
['201.234.178.62', u'Bogot\xe1', 'COLOMBIA', 'CO', '-75.2833,10.4']
Bogot?

Thanks to all who helped.
ak

From keithwins at gmail.com  Sun Jan  5 21:23:21 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 5 Jan 2014 15:23:21 -0500
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <CAO5ffbZMwioCL2VApAkD1Y7p05dMk8ji3b-Cpt=3WOHMAi+Ccw@mail.gmail.com>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
 <CAO5ffbZMwioCL2VApAkD1Y7p05dMk8ji3b-Cpt=3WOHMAi+Ccw@mail.gmail.com>
Message-ID: <CAO5ffbbSZ+wNZe08GpO6perF_B3uojUDNUih+5uCFsmJFZL1eA@mail.gmail.com>

I should have included an example. If you can, and if it doesn't make your
file too long, and if I'm right that this is easy to do in the output
module of wherever this is coming from, add some white space so you can
read/debug easier, though it's not at all necessary (strings have to be
quoted also: see below):

[2, ALA, {C: 178.255, CA: 53.263, CB: 18.411,,,,,,,,,,}]

This is ready to be accessed: If I do this at the command prompt:

shift = [2, "ALA", {"C": 178.255, "CA": 53.263, "CB": 18.411}]

Then:

shift[0] returns 2
shift[2]['CA'] returns 53.263

And if you had a bunch of these in a list shift_list[] (like your original
data set), you could do things like

for i in shift_list:
    for atom in shift_list[i][2]:
        return shift_list[i][2][atom]

I didn't check this code, it's pretty much guaranteed to be wrong but I
think it might point in the right direction.

I think I made this a little more complicated than it needs to be, but I
have to run right now. Maybe this is helpful. Good luck!

Actually, I think shift needs to be a class... but that's just my nascent
OOP comment.

Keith




On Sun, Jan 5, 2014 at 3:01 PM, Keith Winston <keithwins at gmail.com> wrote:

> Hi Amrita, I'm just a beginner but I notice that, after the first two
> entries on each line (i.e. 10,ALA), the rest might fit nicely into a dict,
> like this {H: 8.388, HB1: 1.389, ...}. That would give you a lot of
> flexibility in getting at the values later. It would be easy enough to
> replace the "=" with ':", and add some curly braces. In fact, if you
> enclosed each line in square braces, changed =/: and added the curly braces
> on the dict, then each line would already be a list containing a
> dictionary, and you'd be ready to do some rearranging very easily.
>
> Whether you do that in Python or when you are building your file in
> whatever system it's coming from is your call. If you left off the outer
> braces, each line is a tuple containing a dict, which works too.
>
> Sorry if all I've done is state the obvious here. I warned you I'm a
> beginner.
>
>


-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140105/23e76cd4/attachment.html>

From steve at pearwood.info  Sun Jan  5 23:26:57 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 6 Jan 2014 09:26:57 +1100
Subject: [Tutor] encoding question
In-Reply-To: <CACL+1auwfODNqPZfH5aDtAgcO6mJcODqf8JbbDzjxYyuikYbxQ@mail.gmail.com>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
 <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
 <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net>
 <CACL+1auwfODNqPZfH5aDtAgcO6mJcODqf8JbbDzjxYyuikYbxQ@mail.gmail.com>
Message-ID: <20140105222656.GG29356@ando>

On Sun, Jan 05, 2014 at 11:02:34AM -0500, eryksun wrote:

> Danny walked you through the XML. Note that he didn't decode the
> response. It includes an encoding on the first line:
> 
>     <?xml version="1.0" encoding="ISO-8859-1" ?>

That surprises me. I thought XML was only valid in UTF-8? Or maybe that 
was wishful thinking.

>         tree = ET.fromstring(response.read())

In other words, leave it to ElementTree to manage the decoding and 
encoding itself. Nice -- I like that solution.



-- 
Steven

From steve at pearwood.info  Sun Jan  5 23:44:18 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 6 Jan 2014 09:44:18 +1100
Subject: [Tutor] Fwd:  arrangement of datafile
In-Reply-To: <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
Message-ID: <20140105224418.GH29356@ando>

Hi Amrita,

On Sun, Jan 05, 2014 at 10:01:16AM +0800, Amrita Kumari wrote:

> I have saved my data in csv format now it is looking like this:

If you have a file in CSV format, you should use the csv module to read 
the file.

http://docs.python.org/3/library/csv.html

If you're still using Python 2.x, you can read this instead:

http://docs.python.org/2/library/csv.html


I think that something like this should work for you:

import csv
with open('/path/to/your/file.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

Of course, you can process the rows, not just print them. Each row will 
be a list of strings. For example, you show the first row as this:

> 2,ALA,C=178.255,CA=53.263,CB=18.411,,,,,,,,,,

so the above code should print this for the first row:

['2', 'ALA', 'C=178.255', 'CA=53.263', 'CB=18.411', '', '', '', 
'', '', '', '', '', '']


You can process each field as needed. For example, to convert the 
first field from a string to an int:

        row[0] = int(row[0])

To split the third item 'C=178.255' into a key ('C') and a numeric 
value:

        key, value = row[2].split('=', 1)
        value = float(value.strip())



Now you know how to read CSV files. What do you want to do with the data 
in the file?



-- 
Steven

From akleider at sonic.net  Mon Jan  6 00:03:01 2014
From: akleider at sonic.net (Alex Kleider)
Date: Sun, 05 Jan 2014 15:03:01 -0800
Subject: [Tutor] encoding question
In-Reply-To: <20140105222656.GG29356@ando>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando> <6ca8d91d0c974a627f3909877e2256ab@sonic.net>
 <20140105014945.GC29356@ando> <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
 <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
 <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net>
 <CACL+1auwfODNqPZfH5aDtAgcO6mJcODqf8JbbDzjxYyuikYbxQ@mail.gmail.com>
 <20140105222656.GG29356@ando>
Message-ID: <b6a9d52f36ffaa5a4956c23e603343a4@sonic.net>

On 2014-01-05 14:26, Steven D'Aprano wrote:
> On Sun, Jan 05, 2014 at 11:02:34AM -0500, eryksun wrote:
> 
>> Danny walked you through the XML. Note that he didn't decode the
>> response. It includes an encoding on the first line:
>> 
>>     <?xml version="1.0" encoding="ISO-8859-1" ?>
> 
> That surprises me. I thought XML was only valid in UTF-8? Or maybe that
> was wishful thinking.
> 
>>         tree = ET.fromstring(response.read())

I believe you were correct the first time.
My experience with all of this has been that in spite of the xml having 
been advertised as having been encoded in ISO-8859-1 (which I believe is 
synonymous with Latin-1), my script (specifically Python's xml parser: 
xml.etree.ElementTree) didn't work until the xml was decoded from 
Latin-1 (into Unicode) and then encoded into UTF-8. Here's the snippet 
with some comments mentioning the painful lessons learned:
"""
     response =  urllib2.urlopen(url_format_str %\
                                    (ip_address, ))
     encoding = response.headers.getparam('charset')
     info = response.read().decode(encoding)
     # <info> comes in as <type 'unicode'>.
     n = info.find('\n')
     xml = info[n+1:]  # Get rid of a header line.
     # root = ET.fromstring(xml) # This causes error:
     # UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1'
     # in position 456: ordinal not in range(128)
     root = ET.fromstring(xml.encode("utf-8"))
"""


> 
> In other words, leave it to ElementTree to manage the decoding and
> encoding itself. Nice -- I like that solution.

From eryksun at gmail.com  Mon Jan  6 03:21:13 2014
From: eryksun at gmail.com (eryksun)
Date: Sun, 5 Jan 2014 21:21:13 -0500
Subject: [Tutor] encoding question
In-Reply-To: <20140105222656.GG29356@ando>
References: <0f67356033ea2385876180615faf3ea3@sonic.net>
 <20140104235243.GA29356@ando>
 <6ca8d91d0c974a627f3909877e2256ab@sonic.net> <20140105014945.GC29356@ando>
 <9e202379421c33cda3c81ecfb0a938c6@sonic.net>
 <CAGZAPF5NvEXGbLqbN1N0VAzj2A1mbr5o-P8BFzn10JvDadMp5w@mail.gmail.com>
 <ace7aa764d02040486ab441f98b49c11@sonic.net>
 <CAGZAPF5eDtAQYk+ZrR0oAk6W5pw4nNOVr_oRM7Qjz8aut87+7w@mail.gmail.com>
 <7d4de63d9f43f17fd9a7da9c4530539a@sonic.net>
 <CACL+1auwfODNqPZfH5aDtAgcO6mJcODqf8JbbDzjxYyuikYbxQ@mail.gmail.com>
 <20140105222656.GG29356@ando>
Message-ID: <CACL+1auUaJ_EAaWDH9Q08-ivPRbdKmDj1UbS-jw0Q17h8VqifQ@mail.gmail.com>

On Sun, Jan 5, 2014 at 5:26 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Sun, Jan 05, 2014 at 11:02:34AM -0500, eryksun wrote:
>>
>>     <?xml version="1.0" encoding="ISO-8859-1" ?>
>
> That surprises me. I thought XML was only valid in UTF-8? Or maybe that
> was wishful thinking.

JSON text SHALL be encoded in Unicode:

https://tools.ietf.org/html/rfc4627#section-3

For XML, UTF-8 is recommended by RFC 3023, but not required. Also, the
MIME charset takes precedence. Section 8 has examples:

https://tools.ietf.org/html/rfc3023#section-8

So I was technically wrong to rely on the XML encoding (they happen to
be the same in this case). Instead you can create a parser with the
encoding from the header:

    encoding = response.headers.getparam('charset')
    parser = ET.XMLParser(encoding=encoding)
    tree = ET.parse(response, parser)

The expat parser (pyexpat) used by Python is limited to ASCII, Latin-1
and Unicode transport encodings. So it's probably better to transcode
to UTF-8 as Alex is doing, but then use a custom parser to override
the XML encoding:

    encoding = response.headers.getparam('charset')
    info = response.read().decode(encoding).encode('utf-8')

    parser = ET.XMLParser(encoding='utf-8')
    tree = ET.fromstring(info, parser)

From keithwins at gmail.com  Mon Jan  6 04:04:29 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 5 Jan 2014 22:04:29 -0500
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <20140105224418.GH29356@ando>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
 <20140105224418.GH29356@ando>
Message-ID: <CAO5ffbYPxq6rVGRJvrJt89RSWR4P9p02HmdCspzzUerOS3=bDA@mail.gmail.com>

Amrita, on a closer read of your very first post I (think I) see you
already successfully read your data into a series of dicts (mylist in your
example), so if you still want the output you posted in the first post,
then you can do some version of the loops that I described. That said, I'm
sure Stephen is right about the csv module having helpful tools for parsing
that original file, if you're not past that point. Anyway, if you had all
your mylist in a list of lists (NOT a dict, as you have them) then getting
the output you wanted seems easy. HOWEVER: I don't think you want to strip
off the first two numbers, since I think the first one is critical to your
final listing, no? I might be beating a tired horse here, but you could get
your desired output from such a list of lists like this (I modified the
names, and added back in that first number to the output)

for i in mylist_list:
    for atom in mylist_list[i][2]:
        print(mylist_list[i][0], atom, " = ",
mylist_list[i][2][atom])      # output something like "2 C = 178.255"

This is pretty ugly, but you get the idea. As I mentioned before, putting
it all into a class would allow you to do this more robustly, but I'll
probably lead you astray if I expand on that.

Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140105/143b8d0b/attachment.html>

From keithwins at gmail.com  Mon Jan  6 09:27:39 2014
From: keithwins at gmail.com (Keith Winston)
Date: Mon, 6 Jan 2014 03:27:39 -0500
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <CAO5ffbYPxq6rVGRJvrJt89RSWR4P9p02HmdCspzzUerOS3=bDA@mail.gmail.com>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
 <20140105224418.GH29356@ando>
 <CAO5ffbYPxq6rVGRJvrJt89RSWR4P9p02HmdCspzzUerOS3=bDA@mail.gmail.com>
Message-ID: <CAO5ffbbKPCRE04ojb9kKkUuPsN42EA_gpUm1VyaSfZBKMhcZyQ@mail.gmail.com>

Hi Amrita: I tried to figure out, for kicks, how to do what I THINK is what
you're trying to do... I've never even opened a .txt file in Python before,
so you can take all this with a big grain of salt... Anyway, if you take
your example of your original database:

1 GLY HA2=3.7850 HA3=3.9130
2 SER H=8.8500 HA=4.3370 N=115.7570
3 LYS H=8.7530 HA=4.0340 HB2=1.8080 N=123.2380
 4 LYS H=7.9100 HA=3.8620 HB2=1.7440 HG2=1.4410 N=117.9810
5 LYS H=7.4450 HA=4.0770 HB2=1.7650 HG2=1.4130 N=115.4790
6 LEU H=7.6870 HA=4.2100 HB2=1.3860 HB3=1.6050 HG=1.5130 HD11=0.7690
HD12=0.7690 HD13=0.7690 N=117.3260
7 PHE H=7.8190 HA=4.5540 HB2=3.1360 N=117.0800
8 PRO HD2=3.7450
9 GLN H=8.2350 HA=4.0120 HB2=2.1370 N=116.3660
10 ILE H=7.9790 HA=3.6970 HB=1.8800 HG21=0.8470 HG22=0.8470 HG23=0.8470
HG12=1.6010 HG13=2.1670 N=119.0300
11 ASN H=7.9470 HA=4.3690 HB3=2.5140 N=117.8620
12 PHE H=8.1910 HA=4.1920 HB2=3.1560 N=121.2640
13 LEU H=8.1330 HA=3.8170 HB3=1.7880 HG=1.5810 HD11=0.8620 HD12=0.8620
HD13=0.8620 N=119.1360

I put it in a file ashift.txt. Then:

f = open('ashift.txt', 'r')
lines = f.readlines()

Now I could iterate through lines (it is a list of strings, one per line),
but I just shortcut to play with a single line:

tshift = lines[0]
tshift = tshift.replace("=", ":")
tshift = tshift.splitlines()  # remove the final \n
tshift = tshift.split(" ")

At which point we have something like this:

['1', 'GLY', 'HA2:3.7850', 'HA3:3.9130']

I am out of time, plus I'm very conscious of doing this INCREDIBLY ineptly.
I have spent a bit of time trying to sort out the right way, there might be
some approach involving dialects associated with the csv module, but I
couldn't sort that out. If one could massage the above line (or the
original file) into

[1, 'GLY', {'HA2' : 3.7850, 'HA3' : 3.9130}]

This is what I'd talked about before, and would make reaching your final
output pretty easy, following the stuff I said above.

I KNOW there's a much, much easier way to do this, probably a one-liner (at
least for the file parsing).

You talked about printing this stuff out, but if you are going to process
it further (analyzing it in some way, for example) there might be
implications as to how you proceed with this.

Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140106/ad68330b/attachment.html>

From keithwins at gmail.com  Mon Jan  6 09:35:09 2014
From: keithwins at gmail.com (Keith Winston)
Date: Mon, 6 Jan 2014 03:35:09 -0500
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <CAO5ffbbKPCRE04ojb9kKkUuPsN42EA_gpUm1VyaSfZBKMhcZyQ@mail.gmail.com>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
 <20140105224418.GH29356@ando>
 <CAO5ffbYPxq6rVGRJvrJt89RSWR4P9p02HmdCspzzUerOS3=bDA@mail.gmail.com>
 <CAO5ffbbKPCRE04ojb9kKkUuPsN42EA_gpUm1VyaSfZBKMhcZyQ@mail.gmail.com>
Message-ID: <CAO5ffbaauZ76kgX34cMZhVQ1RWjmWeoEXgC8Qb9HJudYkQjnsQ@mail.gmail.com>

oops, I see Steven pointed out a much cleaner approach. Oh well. Shock &
surprise ;)

Keith


On Mon, Jan 6, 2014 at 3:27 AM, Keith Winston <keithwins at gmail.com> wrote:

> Hi Amrita: I tried to figure out, for kicks, how to do what I THINK is
> what you're trying to do... I've never even opened a .txt file in Python
> before, so you can take all this with a big grain of salt... Anyway, if you
> take your example of your original database:
>
> 1 GLY HA2=3.7850 HA3=3.9130
> 2 SER H=8.8500 HA=4.3370 N=115.7570
> 3 LYS H=8.7530 HA=4.0340 HB2=1.8080 N=123.2380
>  4 LYS H=7.9100 HA=3.8620 HB2=1.7440 HG2=1.4410 N=117.9810
> 5 LYS H=7.4450 HA=4.0770 HB2=1.7650 HG2=1.4130 N=115.4790
> 6 LEU H=7.6870 HA=4.2100 HB2=1.3860 HB3=1.6050 HG=1.5130 HD11=0.7690
> HD12=0.7690 HD13=0.7690 N=117.3260
> 7 PHE H=7.8190 HA=4.5540 HB2=3.1360 N=117.0800
> 8 PRO HD2=3.7450
> 9 GLN H=8.2350 HA=4.0120 HB2=2.1370 N=116.3660
> 10 ILE H=7.9790 HA=3.6970 HB=1.8800 HG21=0.8470 HG22=0.8470 HG23=0.8470
> HG12=1.6010 HG13=2.1670 N=119.0300
> 11 ASN H=7.9470 HA=4.3690 HB3=2.5140 N=117.8620
> 12 PHE H=8.1910 HA=4.1920 HB2=3.1560 N=121.2640
> 13 LEU H=8.1330 HA=3.8170 HB3=1.7880 HG=1.5810 HD11=0.8620 HD12=0.8620
> HD13=0.8620 N=119.1360
>
> I put it in a file ashift.txt. Then:
>
> f = open('ashift.txt', 'r')
> lines = f.readlines()
>
> Now I could iterate through lines (it is a list of strings, one per line),
> but I just shortcut to play with a single line:
>
> tshift = lines[0]
> tshift = tshift.replace("=", ":")
> tshift = tshift.splitlines()  # remove the final \n
> tshift = tshift.split(" ")
>
> At which point we have something like this:
>
> ['1', 'GLY', 'HA2:3.7850', 'HA3:3.9130']
>
> I am out of time, plus I'm very conscious of doing this INCREDIBLY
> ineptly. I have spent a bit of time trying to sort out the right way, there
> might be some approach involving dialects associated with the csv module,
> but I couldn't sort that out. If one could massage the above line (or the
> original file) into
>
> [1, 'GLY', {'HA2' : 3.7850, 'HA3' : 3.9130}]
>
> This is what I'd talked about before, and would make reaching your final
> output pretty easy, following the stuff I said above.
>
> I KNOW there's a much, much easier way to do this, probably a one-liner
> (at least for the file parsing).
>
> You talked about printing this stuff out, but if you are going to process
> it further (analyzing it in some way, for example) there might be
> implications as to how you proceed with this.
>
> Keith
>
>


-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140106/a6640bb4/attachment-0001.html>

From amrita.g13 at gmail.com  Mon Jan  6 09:57:38 2014
From: amrita.g13 at gmail.com (Amrita Kumari)
Date: Mon, 6 Jan 2014 16:57:38 +0800
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <20140105224418.GH29356@ando>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
 <20140105224418.GH29356@ando>
Message-ID: <CAO313kNLTYWBrgEqjZMe3g9iW3kktVPu83RVDJdCSQapwZpBLA@mail.gmail.com>

Hi Steven,

I tried this code:

import csv
with open('file.csv') as f:
     reader = csv.reader(f)
     for row in reader:
         print(row)
         row[0] = int(row[0])

up to this extent it is ok; it is ok it is giving the output as:

['1' , ' GLY' ,  'HA2=3.7850' ,  'HA3=3.9130' , ' ' , ' ' , ' ' , ' ']
[ '2' ,  'SER' ,  'H=8.8500' ,  'HA=4.3370' ,  'N=115.7570' , ' ' , ' ' , '
']
----------------------
-----------------------------------
but the command :

key, value = row[2].split('=', 1)
        value = float(value.strip())
        print(value)

is giving the value of row[2] element as

['1' , ' GLY' ,  'HA2=3.7850' ,  'HA3=3.9130' , ' ' , ' ' , ' ' , ' ']
3.7850
[ '2' ,  'SER' ,  'H=8.8500' ,  'HA=4.3370' ,  'N=115.7570' , ' ' , ' ' , '
']
8.8500
--------------------
------------------
so this is not what I want I want to print all the chemical shift value of
similar atom from each row at one time

like this:

1 HA2=3.7850
2 HA2=nil
3 HA2=nil
.....
............
..........
13 HA2=nil

similarly, for atom HA3:

1 HA3=3.9130
2 HA3=nil
3 HA3=nil
...........
............
............
13 HA3=nil  and so on.

so how to split each item into a key and a numeric value and then search
for similar atom and print its chemical shift value at one time along with
residue no..

Thanks,
Amrita





On Mon, Jan 6, 2014 at 6:44 AM, Steven D'Aprano <steve at pearwood.info> wrote:

> Hi Amrita,
>
> On Sun, Jan 05, 2014 at 10:01:16AM +0800, Amrita Kumari wrote:
>
> > I have saved my data in csv format now it is looking like this:
>
> If you have a file in CSV format, you should use the csv module to read
> the file.
>
> http://docs.python.org/3/library/csv.html
>
> If you're still using Python 2.x, you can read this instead:
>
> http://docs.python.org/2/library/csv.html
>
>
> I think that something like this should work for you:
>
> import csv
> with open('/path/to/your/file.csv') as f:
>     reader = csv.reader(f)
>     for row in reader:
>         print(row)
>
> Of course, you can process the rows, not just print them. Each row will
> be a list of strings. For example, you show the first row as this:
>
> > 2,ALA,C=178.255,CA=53.263,CB=18.411,,,,,,,,,,
>
> so the above code should print this for the first row:
>
> ['2', 'ALA', 'C=178.255', 'CA=53.263', 'CB=18.411', '', '', '',
> '', '', '', '', '', '']
>
>
> You can process each field as needed. For example, to convert the
> first field from a string to an int:
>
>         row[0] = int(row[0])
>
> To split the third item 'C=178.255' into a key ('C') and a numeric
> value:
>
>         key, value = row[2].split('=', 1)
>         value = float(value.strip())
>
>
>
> Now you know how to read CSV files. What do you want to do with the data
> in the file?
>
>
>
> --
> Steven
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140106/ad403eba/attachment.html>

From rafael.knuth at gmail.com  Mon Jan  6 11:59:34 2014
From: rafael.knuth at gmail.com (Rafael Knuth)
Date: Mon, 6 Jan 2014 11:59:34 +0100
Subject: [Tutor] Activating virtualenv in Windows
Message-ID: <CAM-E2X7Bgmzh3akVXePPxgNrK5TNR_ZVnH3Wn1goXDnzAgPVjg@mail.gmail.com>

Hej guys,

does anyone know how to activate virtualenv in Windows?
In Terminal it's:

source bin/activate

Couldn't find the corresponding command for Windows that actually worked.
Any ideas?

Thanks!

Rafael
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140106/eb74fb8c/attachment.html>

From shireenrao at gmail.com  Mon Jan  6 12:35:26 2014
From: shireenrao at gmail.com (Srinivas Nyayapati)
Date: Mon, 6 Jan 2014 06:35:26 -0500
Subject: [Tutor] Activating virtualenv in Windows
In-Reply-To: <CAM-E2X7Bgmzh3akVXePPxgNrK5TNR_ZVnH3Wn1goXDnzAgPVjg@mail.gmail.com>
References: <CAM-E2X7Bgmzh3akVXePPxgNrK5TNR_ZVnH3Wn1goXDnzAgPVjg@mail.gmail.com>
Message-ID: <6186509829526161835@unknownmsgid>

Hello

> On Jan 6, 2014, at 6:08 AM, Rafael Knuth <rafael.knuth at gmail.com> wrote:
>
> Hej guys,
>
> does anyone know how to activate virtualenv in Windows?
> In Terminal it's:
>
> source bin/activate


Just run the script directly from the prompt -

C:/<virtualenv location>/bin/activate

HTH
-Srini

From eryksun at gmail.com  Mon Jan  6 13:01:56 2014
From: eryksun at gmail.com (eryksun)
Date: Mon, 6 Jan 2014 07:01:56 -0500
Subject: [Tutor] Activating virtualenv in Windows
In-Reply-To: <CAM-E2X7Bgmzh3akVXePPxgNrK5TNR_ZVnH3Wn1goXDnzAgPVjg@mail.gmail.com>
References: <CAM-E2X7Bgmzh3akVXePPxgNrK5TNR_ZVnH3Wn1goXDnzAgPVjg@mail.gmail.com>
Message-ID: <CACL+1aufeQS7mxQ4Nd9mVZivFNB3ZzKYigRDga3+vcGcFXesTA@mail.gmail.com>

On Mon, Jan 6, 2014 at 5:59 AM, Rafael Knuth <rafael.knuth at gmail.com> wrote:
>
> does anyone know how to activate virtualenv in Windows?
> In Terminal it's:
>
> source bin/activate
>
> Couldn't find the corresponding command for Windows that actually worked.
> Any ideas?

Scripts are installed to `Scripts` on Windows.

http://www.virtualenv.org/en/latest/virtualenv.html#windows-notes

http://www.virtualenv.org/en/latest/virtualenv.html#activate-script

From denis.spir at gmail.com  Mon Jan  6 12:58:10 2014
From: denis.spir at gmail.com (spir)
Date: Mon, 06 Jan 2014 12:58:10 +0100
Subject: [Tutor] More or less final Chutes & Ladders
In-Reply-To: <CAO5ffbb7TjJ=_A3FZ+NX9q1XQRmxxmGTJRktut8Wrk0XPOF2ww@mail.gmail.com>
References: <CAO5ffbanyfgLopdts6i8JRuy2mizQAFKQdaj6nB0mUnTVYtKRA@mail.gmail.com>
 <52C7DD5D.6000700@gmail.com>
 <CAO5ffbbMCf83u5r3xw6V6Q_VNWUhStHcJMZW9eJnWz1JDQ12YA@mail.gmail.com>
 <52C7F57D.4060600@gmail.com>
 <CAO5ffbaNu2vpjm5KKUx20KN+vpbe_fjqE4pP6g1B1fo_6tE6ow@mail.gmail.com>
 <20140104130324.GY29356@ando> <52C80BE4.3000305@gmail.com>
 <CAO5ffbaWhjM1kT__AeaJDuMtarpDJwTGDJxusibtu-S2TzW-fg@mail.gmail.com>
 <lab2vt$oin$1@ger.gmane.org>
 <CAO5ffbb7TjJ=_A3FZ+NX9q1XQRmxxmGTJRktut8Wrk0XPOF2ww@mail.gmail.com>
Message-ID: <52CA9A52.7080805@gmail.com>

On 01/05/2014 08:40 PM, Keith Winston wrote:
> On Sun, Jan 5, 2014 at 2:52 AM, Mark Lawrence <breamoreboy at yahoo.co.uk>wrote:
>
>> Homework for you :)  Write a line of code that creates a list of say 3 or
>> 4 integers, then write a line that creates a tuple with the same integers.
>>   Use the dis module to compare the byte code that the two lines of code
>> produce.  The difference is interesting.
>
>
>
> Well... that was a very interesting assignment, though I'm going to have to
> chew on it for a while to understand. I can see that the processing code
> for a tuple is considerably shorter... it is processed in a gulp instead of
> bite by byte... it doesn't have the "Build List" step at all (what goes on
> inside of THAT?)... but I can't claim to really understand what I'm looking
> at.
>
> I notice, for example, if I include only constants (immutable types) in my
> tuple, then it does that gulp thing. If I include a list in there too, all
> hell breaks loose, and suddenly I'm Building Tuples (what goes on inside of
> THAT?). A tuple of tuples still goes down in a single swallow, of course.
>
> Sadly, you can see how my mind works here... hey, this was FUN! You can
> assign me homework any time, teach!

A version of Mark's assigment, with only simple tuple items, but some consts and 
some vars:

from dis import dis

x,y = 1,2

def f (i,j):           # line 5 in source
     a,b = 1,2
     t1 = (1,2)
     t2 = (a,b)
     t3 = (x,y)
     t4 = (i,j)
     l = [1,2]

print(dis(f))

   6           0 LOAD_CONST               3 ((1, 2))
               3 UNPACK_SEQUENCE          2
               6 STORE_FAST               2 (a)
               9 STORE_FAST               3 (b)

   7          12 LOAD_CONST               4 ((1, 2))
              15 STORE_FAST               4 (t1)

   8          18 LOAD_FAST                2 (a)
              21 LOAD_FAST                3 (b)
              24 BUILD_TUPLE              2
              27 STORE_FAST               5 (t2)

   9          30 LOAD_GLOBAL              0 (x)
              33 LOAD_GLOBAL              1 (y)
              36 BUILD_TUPLE              2
              39 STORE_FAST               6 (t3)

  10          42 LOAD_FAST                0 (i)
              45 LOAD_FAST                1 (j)
              48 BUILD_TUPLE              2
              51 STORE_FAST               7 (t4)

  11          54 LOAD_CONST               1 (1)
              57 LOAD_CONST               2 (2)
              60 BUILD_LIST               2
              63 STORE_FAST               8 (l)
              66 LOAD_CONST               0 (None)
              69 RETURN_VALUE

[I call here const a value that is always the same, at every execution; thus in 
principle know not only to the programmer, but to the compiler. I don't mean 
immutable.]

The interesting part for me is the difference of construction when tuple items 
are variable: the build_tuple routine. t2 is also const, abeit so-to-say an 
"implicit" const tuple, while t1 is explicitely const, in value notation itself. 
t2 is variable, since x & y may change in the meantime (between their first def 
and call to f). t3 is variable by so-to-say definition of "variable".

This is a kind of little optimisation in the case a tuple is obviously const. It 
is probably worth it because tuples are fix-size, since they are immutable (they 
may just be fix-size arrays in the backstage, I don't know). Certainly python 
does not even attempt such an optimisation for list due to their mutable and 
flexible-size structure (they are flexible-size, dynamic arrays).

Denis

From keithwins at gmail.com  Mon Jan  6 17:26:51 2014
From: keithwins at gmail.com (Keith Winston)
Date: Mon, 6 Jan 2014 11:26:51 -0500
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <CAO313kNLTYWBrgEqjZMe3g9iW3kktVPu83RVDJdCSQapwZpBLA@mail.gmail.com>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
 <20140105224418.GH29356@ando>
 <CAO313kNLTYWBrgEqjZMe3g9iW3kktVPu83RVDJdCSQapwZpBLA@mail.gmail.com>
Message-ID: <CAO5ffbbNs5wLeMZ_84sir_hWaYt3FieR2mnZ14_DU2zoaeWW1g@mail.gmail.com>

Amrita, it doesn't seem like the code you are providing is the code you are
running. I wonder if you are running it all at the Python command line or
something, and have to type it in every time? You should put it in a file,
and save & run that file,  and then cut and paste it directly into your
emails, so we can see what you're actually running. There are a number of
small things in the code you've posted that wouldn't run, I think...

Keith


On Mon, Jan 6, 2014 at 3:57 AM, Amrita Kumari <amrita.g13 at gmail.com> wrote:

> Hi Steven,
>
> I tried this code:
>
> import csv
> with open('file.csv') as f:
>      reader = csv.reader(f)
>      for row in reader:
>          print(row)
>          row[0] = int(row[0])
>
> up to this extent it is ok; it is ok it is giving the output as:
>
> ['1' , ' GLY' ,  'HA2=3.7850' ,  'HA3=3.9130' , ' ' , ' ' , ' ' , ' ']
> [ '2' ,  'SER' ,  'H=8.8500' ,  'HA=4.3370' ,  'N=115.7570' , ' ' , ' ' ,
> ' ']
> ----------------------
> -----------------------------------
> but the command :
>
> key, value = row[2].split('=', 1)
>         value = float(value.strip())
>         print(value)
>
> is giving the value of row[2] element as
>
> ['1' , ' GLY' ,  'HA2=3.7850' ,  'HA3=3.9130' , ' ' , ' ' , ' ' , ' ']
> 3.7850
> [ '2' ,  'SER' ,  'H=8.8500' ,  'HA=4.3370' ,  'N=115.7570' , ' ' , ' ' ,
> ' ']
> 8.8500
> --------------------
> ------------------
> so this is not what I want I want to print all the chemical shift value of
> similar atom from each row at one time
>
> like this:
>
> 1 HA2=3.7850
> 2 HA2=nil
> 3 HA2=nil
> .....
> ............
> ..........
> 13 HA2=nil
>
> similarly, for atom HA3:
>
> 1 HA3=3.9130
> 2 HA3=nil
> 3 HA3=nil
> ...........
> ............
> ............
> 13 HA3=nil  and so on.
>
> so how to split each item into a key and a numeric value and then search
> for similar atom and print its chemical shift value at one time along with
> residue no..
>
> Thanks,
> Amrita
>
>
>
>
>
> On Mon, Jan 6, 2014 at 6:44 AM, Steven D'Aprano <steve at pearwood.info>wrote:
>
>> Hi Amrita,
>>
>> On Sun, Jan 05, 2014 at 10:01:16AM +0800, Amrita Kumari wrote:
>>
>> > I have saved my data in csv format now it is looking like this:
>>
>> If you have a file in CSV format, you should use the csv module to read
>> the file.
>>
>> http://docs.python.org/3/library/csv.html
>>
>> If you're still using Python 2.x, you can read this instead:
>>
>> http://docs.python.org/2/library/csv.html
>>
>>
>> I think that something like this should work for you:
>>
>> import csv
>> with open('/path/to/your/file.csv') as f:
>>     reader = csv.reader(f)
>>     for row in reader:
>>         print(row)
>>
>> Of course, you can process the rows, not just print them. Each row will
>> be a list of strings. For example, you show the first row as this:
>>
>> > 2,ALA,C=178.255,CA=53.263,CB=18.411,,,,,,,,,,
>>
>> so the above code should print this for the first row:
>>
>> ['2', 'ALA', 'C=178.255', 'CA=53.263', 'CB=18.411', '', '', '',
>> '', '', '', '', '', '']
>>
>>
>> You can process each field as needed. For example, to convert the
>> first field from a string to an int:
>>
>>         row[0] = int(row[0])
>>
>> To split the third item 'C=178.255' into a key ('C') and a numeric
>> value:
>>
>>         key, value = row[2].split('=', 1)
>>         value = float(value.strip())
>>
>>
>>
>> Now you know how to read CSV files. What do you want to do with the data
>> in the file?
>>
>>
>>
>> --
>> Steven
>> _______________________________________________
>> 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
>
>


-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140106/c2a78956/attachment-0001.html>

From chigga101 at gmail.com  Mon Jan  6 17:38:06 2014
From: chigga101 at gmail.com (Matthew Ngaha)
Date: Mon, 6 Jan 2014 16:38:06 +0000
Subject: [Tutor] ubuntu hassles.
Message-ID: <CACzNyA3JwFNsThc0tKcZkVmZJnN-GDuSBxs0H1mo=HAvkWo4nw@mail.gmail.com>

Hi i wrote about a week ago about the problems i had with importing
sqlite3 on python 3.3 on ubuntu 12.04. Due to this ive tried to revert
back to python 3.2 which is the default installation along wit 2.7.
I've run into 2 problems.

1) I'm new to ubuntu and someone helped me install python3.3 from
source. I've tried 'make uninstall' from the dir containing the source
package but it seems there is no way to get this version off my
computer.

2) I really need to use virtualenv for python3.2. The problem is
python3.3 seems to be the default and overrides every virtualenv thing
i try doing. whether it is pyvenv or virtualenv, the 3.3 version takes
priority. It is located in /usr/local/bin  ... I have no idea where my
3.2 virtualenv is located although i know i definately installed it
with :
              sudo apt-get install python-virtualenv

if i can achieve 1) or 2) im sure the rest would be straightforward.
any ideas? I know this isn't really a python issue but it's a last
resort as the ubuntu guys are unsure of how to solve this. If i can't
resolve it, not to worry, i'll just upgrade my ubuntu to a more recent
version.

Thanks

From alan.gauld at btinternet.com  Mon Jan  6 18:18:02 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 06 Jan 2014 17:18:02 +0000
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <CAO313kNLTYWBrgEqjZMe3g9iW3kktVPu83RVDJdCSQapwZpBLA@mail.gmail.com>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
 <20140105224418.GH29356@ando>
 <CAO313kNLTYWBrgEqjZMe3g9iW3kktVPu83RVDJdCSQapwZpBLA@mail.gmail.com>
Message-ID: <laeofu$4gr$1@ger.gmane.org>

On 06/01/14 08:57, Amrita Kumari wrote:

> up to this extent it is ok; it is ok it is giving the output as:
>
> ['1' , ' GLY' ,  'HA2=3.7850' ,  'HA3=3.9130' , ' ' , ' ' , ' ' , ' ']
> [ '2' ,  'SER' ,  'H=8.8500' ,  'HA=4.3370' ,  'N=115.7570' , ' ' , ' '
> , ' ']
> ----------------------
> -----------------------------------
> but the command :
>
> key, value = row[2].split('=', 1)
> value = float(value.strip())
> print(value)
>
> is giving the value of row[2] element as
>
> ['1' , ' GLY' ,  'HA2=3.7850' ,  'HA3=3.9130' , ' ' , ' ' , ' ' , ' ']
> 3.7850

Which is correct...

> so this is not what I want I want to print all the chemical shift value
> of similar atom from each row at one time
>
> like this:
>
> 1 HA2=3.7850

Which is a combination of the values available to you.

row[0], key, '=', value

So you can put that together in a print as

print (row[0], key, '=', value)

> similarly, for atom HA3:

I didn't look at the original data in enough fetail to
know if thats a trivial addition or more.

But can you get the above formatting first?

> so how to split each item into a key and a numeric value

Steven showed you that, you just needed to stitch the bits together in 
your desired format.


> and then search for similar atom and print its chemical shift
> value at one time along with residue no..

Let's solve one problem at a time...


HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From wolf.halton at gmail.com  Mon Jan  6 23:56:50 2014
From: wolf.halton at gmail.com (Wolf Halton)
Date: Mon, 6 Jan 2014 17:56:50 -0500
Subject: [Tutor] ubuntu hassles.
In-Reply-To: <CACzNyA3JwFNsThc0tKcZkVmZJnN-GDuSBxs0H1mo=HAvkWo4nw@mail.gmail.com>
References: <CACzNyA3JwFNsThc0tKcZkVmZJnN-GDuSBxs0H1mo=HAvkWo4nw@mail.gmail.com>
Message-ID: <CALRLYEmG3Y0yisSgTZt8wqhKOV1TU40aYqvQQ984rEwc4+1M9w@mail.gmail.com>

consider this:
sudo apt-get search python3
to find out the exact name or how python 3.3 is registered
sudo apt-get uninstall [that-exact-name]
sudo apt-get reinstall python32
sudo apt-get reinstall python-virtualenv




Wolf Halton

--
This Apt Has Super Cow Powers - http://sourcefreedom.com
Security in the Cloud -
http://AtlantaCloudTech.com<http://atlantaCloudTech.com>



On Mon, Jan 6, 2014 at 11:38 AM, Matthew Ngaha <chigga101 at gmail.com> wrote:

> Hi i wrote about a week ago about the problems i had with importing
> sqlite3 on python 3.3 on ubuntu 12.04. Due to this ive tried to revert
> back to python 3.2 which is the default installation along wit 2.7.
> I've run into 2 problems.
>
> 1) I'm new to ubuntu and someone helped me install python3.3 from
> source. I've tried 'make uninstall' from the dir containing the source
> package but it seems there is no way to get this version off my
> computer.
>
> 2) I really need to use virtualenv for python3.2. The problem is
> python3.3 seems to be the default and overrides every virtualenv thing
> i try doing. whether it is pyvenv or virtualenv, the 3.3 version takes
> priority. It is located in /usr/local/bin  ... I have no idea where my
> 3.2 virtualenv is located although i know i definately installed it
> with :
>               sudo apt-get install python-virtualenv
>
> if i can achieve 1) or 2) im sure the rest would be straightforward.
> any ideas? I know this isn't really a python issue but it's a last
> resort as the ubuntu guys are unsure of how to solve this. If i can't
> resolve it, not to worry, i'll just upgrade my ubuntu to a more recent
> version.
>
> Thanks
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140106/120ea6d8/attachment.html>

From kfiresmith at gmail.com  Mon Jan  6 19:55:33 2014
From: kfiresmith at gmail.com (Kodiak Firesmith)
Date: Mon, 6 Jan 2014 13:55:33 -0500
Subject: [Tutor] ubuntu hassles.
In-Reply-To: <CACzNyA3JwFNsThc0tKcZkVmZJnN-GDuSBxs0H1mo=HAvkWo4nw@mail.gmail.com>
References: <CACzNyA3JwFNsThc0tKcZkVmZJnN-GDuSBxs0H1mo=HAvkWo4nw@mail.gmail.com>
Message-ID: <CALh5p2vdm4SC=3c48RqgY0N+=qThi4WtkAm3mWM3ELP7tWTfCQ@mail.gmail.com>

Hello Matthew,
You likely want to investigate the Linux "Alternatives" system which
handles default pointers to a given version of a program.  People usually
encounter this system for the first time while dealing with different
versions of Java JRE needing to be installed at the same time.

I'm a Redhat guy so I can't walk you through it step by step, but I was
able to pull up some Ubuntu documentation on this system here:
http://manpages.ubuntu.com/manpages/lucid/en/man8/update-alternatives.8.html

Hope this helps!

 - Kodiak Firesmith


On Mon, Jan 6, 2014 at 11:38 AM, Matthew Ngaha <chigga101 at gmail.com> wrote:

> Hi i wrote about a week ago about the problems i had with importing
> sqlite3 on python 3.3 on ubuntu 12.04. Due to this ive tried to revert
> back to python 3.2 which is the default installation along wit 2.7.
> I've run into 2 problems.
>
> 1) I'm new to ubuntu and someone helped me install python3.3 from
> source. I've tried 'make uninstall' from the dir containing the source
> package but it seems there is no way to get this version off my
> computer.
>
> 2) I really need to use virtualenv for python3.2. The problem is
> python3.3 seems to be the default and overrides every virtualenv thing
> i try doing. whether it is pyvenv or virtualenv, the 3.3 version takes
> priority. It is located in /usr/local/bin  ... I have no idea where my
> 3.2 virtualenv is located although i know i definately installed it
> with :
>               sudo apt-get install python-virtualenv
>
> if i can achieve 1) or 2) im sure the rest would be straightforward.
> any ideas? I know this isn't really a python issue but it's a last
> resort as the ubuntu guys are unsure of how to solve this. If i can't
> resolve it, not to worry, i'll just upgrade my ubuntu to a more recent
> version.
>
> Thanks
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140106/3fafa258/attachment.html>

From eryksun at gmail.com  Tue Jan  7 01:40:02 2014
From: eryksun at gmail.com (eryksun)
Date: Mon, 6 Jan 2014 19:40:02 -0500
Subject: [Tutor] ubuntu hassles.
In-Reply-To: <CACzNyA3JwFNsThc0tKcZkVmZJnN-GDuSBxs0H1mo=HAvkWo4nw@mail.gmail.com>
References: <CACzNyA3JwFNsThc0tKcZkVmZJnN-GDuSBxs0H1mo=HAvkWo4nw@mail.gmail.com>
Message-ID: <CACL+1auEki=9a_j3XfddCYRXri0LosziXz+Pb2R+GGcnAzJSfQ@mail.gmail.com>

On Mon, Jan 6, 2014 at 11:38 AM, Matthew Ngaha <chigga101 at gmail.com> wrote:
>
> 2) I really need to use virtualenv for python3.2. The problem is
> python3.3 seems to be the default and overrides every virtualenv thing
> i try doing. whether it is pyvenv or virtualenv, the 3.3 version takes
> priority. It is located in /usr/local/bin  ... I have no idea where my
> 3.2 virtualenv is located although i know i definately installed it
> with :
>               sudo apt-get install python-virtualenv


virtualenv allows you to specify the target Python:

    virtualenv --python=/usr/bin/python3.3 myenv

Refer to `man virtualenv` for more options.

FYI, here are some commands to introspect a Debian package in the shell:

    apt-cache search virtualenv        # find packages
    apt-cache show python-virtualenv   # description
    apt-cache policy python-virtualenv # installed version

    apt-file show python-virtualenv    # list files

Or use synaptic if you prefer a GUI interface.

> 1) I'm new to ubuntu and someone helped me install python3.3 from
> source. I've tried 'make uninstall' from the dir containing the source
> package but it seems there is no way to get this version off my
> computer.

Ubuntu has a Python 3.3 package. Installation should be simple:

    $ sudo apt-get update
    $ sudo apt-get install python3.3

If you're building from source, or need to uninstall after a previous
`make install`, use checkinstall to build a package.

Start by installing dependencies.

    $ sudo -s
    # apt-get update
    # apt-get build-dep python3
    # apt-get install checkinstall

Change to the source directory to configure and build Python.

    # ./configure
    # make clean
    # make
    # make test

Installation defaults to /usr/local. Use the configure option
`--prefix` to target a different directory. Obviously you want to
leave the default if your goal is to uninstall a previous installation
that used the defaults. Refer to `./configure --help` for more
options.

Run checkinstall to create and install a Debian package (-D):

    # checkinstall -D --default --fstrans=no\
    --pkgname=python3.3-local --pkgversion=3.3.3-1\
    make install

Omit `--default` if you don't want the default answers to prompts. In
my experience, filesystem translation (fstrans) has to be disabled to
install Python. Change the last part to `make altinstall` if you want
the major and minor version number used for the files in
/usr/local/bin (e.g. pyvenv-3.3). It's a good idea, but obviously not
if your goal is to uninstall a previous "make install".

When it's finished installing, checkinstall should print the path to
the .deb file and also the command you'll need to uninstall the
package, such as:

    # dpkg -r python3.3-local

From chigga101 at gmail.com  Tue Jan  7 03:55:50 2014
From: chigga101 at gmail.com (Matthew Ngaha)
Date: Tue, 7 Jan 2014 02:55:50 +0000
Subject: [Tutor] ubuntu hassles.
In-Reply-To: <CACL+1auEki=9a_j3XfddCYRXri0LosziXz+Pb2R+GGcnAzJSfQ@mail.gmail.com>
References: <CACzNyA3JwFNsThc0tKcZkVmZJnN-GDuSBxs0H1mo=HAvkWo4nw@mail.gmail.com>
 <CACL+1auEki=9a_j3XfddCYRXri0LosziXz+Pb2R+GGcnAzJSfQ@mail.gmail.com>
Message-ID: <CACzNyA2pWT7bCMvj7p5MvEDUG34xaZ5AV8a3mK3xxEbuNSW68A@mail.gmail.com>

On Tue, Jan 7, 2014 at 12:40 AM, eryksun <eryksun at gmail.com> wrote:

>
> virtualenv allows you to specify the target Python:
>
>     virtualenv --python=/usr/bin/python3.3 myenv
>
> Refer to `man virtualenv` for more options.
>
> Or use synaptic if you prefer a GUI interface.
>

> Ubuntu has a Python 3.3 package. Installation should be simple:
>
>     $ sudo apt-get update
>     $ sudo apt-get install python3.3
>
> If you're building from source, or need to uninstall after a previous
> `make install`, use checkinstall to build a package.
>

I'm currently studying/coding on windows but thanks so so much for
this detailed response. I will try again tomorrow, but im now very
confident! thanks again:)

From mesrod at juno.com  Tue Jan  7 04:31:22 2014
From: mesrod at juno.com (mesrod at juno.com)
Date: Tue, 7 Jan 2014 03:31:22 GMT
Subject: [Tutor] ubuntu hassles.
Message-ID: <20140106.203122.10365.0@webmail02.vgs.untd.com>

I tried eryksun's suggestion on installing python3.3: 
"Ubuntu has a Python 3.3 package. Installation should be simple:
    $ sudo apt-get update
    $ sudo apt-get install python3.3"
on my Ubuntu 12.04 system and got the following message:
E: Unable to locate package python3.3
E: Couldn't find any package by regex 'python3.3'
Eugene Rodriguez


From eryksun at gmail.com  Tue Jan  7 05:01:48 2014
From: eryksun at gmail.com (eryksun)
Date: Mon, 6 Jan 2014 23:01:48 -0500
Subject: [Tutor] ubuntu hassles.
In-Reply-To: <20140106.203122.10365.0@webmail02.vgs.untd.com>
References: <20140106.203122.10365.0@webmail02.vgs.untd.com>
Message-ID: <CACL+1avW8k0Uq4gLCaEu4F3dO3K8D7VhA9nczK5QnOMFnwDrhg@mail.gmail.com>

On Mon, Jan 6, 2014 at 10:31 PM, mesrod at juno.com <mesrod at juno.com> wrote:
> I tried eryksun's suggestion on installing python3.3:
> "Ubuntu has a Python 3.3 package. Installation should be simple:
>     $ sudo apt-get update
>     $ sudo apt-get install python3.3"
> on my Ubuntu 12.04 system and got the following message:
> E: Unable to locate package python3.3
> E: Couldn't find any package by regex 'python3.3'
> Eugene Rodriguez

The 3.3 package was added in Quantal (12.10):

http://packages.ubuntu.com/quantal/python3.3

For 12.04 you can add the deadsnakes PPA:

https://launchpad.net/~fkrull/+archive/deadsnakes

>From source, you can use the `--prefix` configure option to install to
/opt or your home directory, or use checkinstall to create a local
package.

From dalveen at gmail.com  Tue Jan  7 10:49:04 2014
From: dalveen at gmail.com (Jorge L.)
Date: Tue, 7 Jan 2014 10:49:04 +0100
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized integer
Message-ID: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>

I'm working through Project Euler problems, now I'm at problem 3. I did an
implementation of the shieve of Erastothenes to find the prime numbers less
than a given number. Then I run a divisibility test over those prime
numbers to find the largest prime factor of that given number. Here's the
code:

import time

def main():
    n = input("Please enter the number to find its highest prime factor: ")
    start_time = time.clock()
    l = p(n)
    div(n,l)
    print "Execution time = ",time.clock() - start_time, "seconds"


# Sieve of Eratosthenes implementation

def p(n):
    is_p=[False]*2 + [True]*(n-1)
    l=[]
    for i in range(2, int(n**0.5)):
        if is_p[i]:
            for j in range(i*i, n, i):
                is_p[j] = False
    for i in range(2, n):
        if is_p[i]:
            l.append(i)
    return l

def div(n,l):
    for p in l :
        if n%p == 0 :
            h=p
    print h

if __name__ == "__main__":
    main()


When i test that script against 600851475143 I get the following error

How may I solve the issue?

Thanks.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/5e0eb80e/attachment.html>

From alan.gauld at btinternet.com  Tue Jan  7 11:50:51 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 07 Jan 2014 10:50:51 +0000
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
Message-ID: <lagm5v$3bo$1@ger.gmane.org>

On 07/01/14 09:49, Jorge L. wrote:
> I'm working through Project Euler problems, now I'm at problem 3. I did
> an implementation of the shieve of Erastothenes to find the prime
> numbers less than a given number. Then I run a divisibility test over
> those prime numbers to find the largest prime factor of that given
> number.

Please, always send the full error text not a summary.
The error message is full of useful information that helps us see 
exactly what was going on at the time.

It also helps if you tell us which version of Python and OS you are 
using. In this case the OS probably doesn't matter, but I assume you are 
on Python 2.X?

Here's the code:
>
> import time
>
> def main():
>      n = input("Please enter the number to find its highest prime factor: ")
>      start_time = time.clock()
>      l = p(n)
>      div(n,l)
>      print "Execution time = ",time.clock() - start_time, "seconds"
>
>
> # Sieve of Eratosthenes implementation
>
> def p(n):
>      is_p=[False]*2 + [True]*(n-1)

If n is large this will create a large list.
Do you have enough memory for a list with
600851475144 members? It may also have
something to do with your indexing problem.
I certainly can't create anything so big on
my PC.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From eryksun at gmail.com  Tue Jan  7 11:58:58 2014
From: eryksun at gmail.com (eryksun)
Date: Tue, 7 Jan 2014 05:58:58 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
Message-ID: <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>

On Tue, Jan 7, 2014 at 4:49 AM, Jorge L. <dalveen at gmail.com> wrote:
>
> When i test that script against 600851475143 I get the following error

You're trying to create a list with over 600 billion items.
sys.maxsize is a bit over 2 billion for 32-bit CPython, but switching
to 64-bit won't help unless you have a few terabytes of memory (8
bytes per pointer). You need to rethink your approach to generating
primes.

From steve at pearwood.info  Tue Jan  7 12:30:05 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Tue, 7 Jan 2014 22:30:05 +1100
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <CAO313kNLTYWBrgEqjZMe3g9iW3kktVPu83RVDJdCSQapwZpBLA@mail.gmail.com>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
 <20140105224418.GH29356@ando>
 <CAO313kNLTYWBrgEqjZMe3g9iW3kktVPu83RVDJdCSQapwZpBLA@mail.gmail.com>
Message-ID: <20140107113002.GJ29356@ando>

On Mon, Jan 06, 2014 at 04:57:38PM +0800, Amrita Kumari wrote:
> Hi Steven,
> 
> I tried this code:
> 
> import csv
> with open('file.csv') as f:
>      reader = csv.reader(f)
>      for row in reader:
>          print(row)
>          row[0] = int(row[0])
> 
> up to this extent it is ok; it is ok it is giving the output as:
> 
> ['1' , ' GLY' ,  'HA2=3.7850' ,  'HA3=3.9130' , ' ' , ' ' , ' ' , ' ']
> [ '2' ,  'SER' ,  'H=8.8500' ,  'HA=4.3370' ,  'N=115.7570' , ' ' , ' ' , '
> ']

It looks like you are re-typing the output into your email. It is much 
better if you copy and paste it so that we can see exactly what happens.


> but the command :
> 
> key, value = row[2].split('=', 1)
>         value = float(value.strip())
>         print(value)
> 
> is giving the value of row[2] element as
> 
> ['1' , ' GLY' ,  'HA2=3.7850' ,  'HA3=3.9130' , ' ' , ' ' , ' ' , ' ']
> 3.7850
> [ '2' ,  'SER' ,  'H=8.8500' ,  'HA=4.3370' ,  'N=115.7570' , ' ' , ' ' , '
> ']
> 8.8500

So far, the code is doing exactly what you told it to do. Take the third 
column (index 2), and split on the equals sign. Convert the part on the 
right of the equals sign to a float, and print the float.


> so this is not what I want I want to print all the chemical shift value of
> similar atom from each row at one time

Okay, then do so. You'll have to write some code to do this.


> like this:
> 
> 1 HA2=3.7850
> 2 HA2=nil
> 3 HA2=nil

Where do these values come from? 



> .....
> ............
> ..........
> 13 HA2=nil
> 
> similarly, for atom HA3:
> 
> 1 HA3=3.9130
> 2 HA3=nil
> 3 HA3=nil
> ...........
> ............
> ............
> 13 HA3=nil  and so on.
> 
> so how to split each item into a key and a numeric value 

I've already shown you how to split an item into a key and numeric 
value. Here it is again:

key, value = item.split('=', 1)
value = float(value)


> and then search
> for similar atom and print its chemical shift value at one time along with
> residue no..

I don't know what a chemical shift value and residue number are. 
Remember, we are Python programmers, not chemists or biochemists or 
whatever your field is. We don't know how to solve your problem, but if 
you describe in simple English terms how you would solve that problem, 
we can probably help you turn it into Python code.

Start with one row, containing this data:

'2', 'SER', 'H=8.8500', 'HA=4.3370', 'N=115.7570', '', '', ''

There are eight columns. What do those columns represent? In simple 
English terms, what would you like to do with those columns? Tell us 
step by step, as if you were explaining to a small child or a computer.



-- 
Steven

From fomcl at yahoo.com  Tue Jan  7 15:19:02 2014
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Tue, 7 Jan 2014 06:19:02 -0800 (PST)
Subject: [Tutor] Activating virtualenv in Windows
Message-ID: <1389104342.67795.BPMail_high_noncarrier@web163806.mail.gq1.yahoo.com>






------------------------------
On Mon, Jan 6, 2014 1:01 PM CET eryksun wrote:

>On Mon, Jan 6, 2014 at 5:59 AM, Rafael Knuth <rafael.knuth at gmail.com> wrote:
>>
>> does anyone know how to activate virtualenv in Windows?

====>>  Virtualevwrapper works great  on Linux, maybe on Widows too:
https://pypi.python.org/pypi/virtualenvwrapper-win/1.1.5

>>
>> source bin/activate
>>
>> Couldn't find the corresponding command for Windows that actually worked.
>> Any ideas?
>
>Scripts are installed to `Scripts` on Windows.
>
>http://www.virtualenv.org/en/latest/virtualenv.html#windows-notes
>
>http://www.virtualenv.org/en/latest/virtualenv.html#activate-script
>_______________________________________________
>Tutor maillist  -  Tutor at python.org
>To unsubscribe or change subscription options:
>https://mail.python.org/mailman/listinfo/tutor


From keithwins at gmail.com  Tue Jan  7 18:55:11 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 7 Jan 2014 12:55:11 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
Message-ID: <CAO5ffbbTR8D3GJbsAPvPVP-u2YfhqndoHSSGouM17XH4gA4MYA@mail.gmail.com>

I had heard of Project Euler long ago, but completely forgotten it. It
looks fun!! Thanks for reminding me of it.

Keith


On Tue, Jan 7, 2014 at 5:58 AM, eryksun <eryksun at gmail.com> wrote:

> On Tue, Jan 7, 2014 at 4:49 AM, Jorge L. <dalveen at gmail.com> wrote:
> >
> > When i test that script against 600851475143 I get the following error
>
> You're trying to create a list with over 600 billion items.
> sys.maxsize is a bit over 2 billion for 32-bit CPython, but switching
> to 64-bit won't help unless you have a few terabytes of memory (8
> bytes per pointer). You need to rethink your approach to generating
> primes.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/688b1c44/attachment.html>

From dyoo at hashcollision.org  Tue Jan  7 19:20:20 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 7 Jan 2014 10:20:20 -0800
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
Message-ID: <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>

As eryksun points out, the memory requirements for a sieve this large
make that approach untenable.

For this particular problem, brute force factoring the number can
work.  That particular number has primes that are much smaller than
the number itself: you should be able to do a simple range loop to
pick them out.

From keithwins at gmail.com  Tue Jan  7 21:11:25 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 7 Jan 2014 15:11:25 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
Message-ID: <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>

I think your approach is fine, you might need to fine tune your algorithm.

hint below.











if you want it: is_p doesn't need to be nearly as big as you specify. There
are a couple other minor problems.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/75ec7ea8/attachment.html>

From dyoo at hashcollision.org  Tue Jan  7 21:46:04 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 7 Jan 2014 12:46:04 -0800
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
Message-ID: <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>

Hi Keith,

I have disagree with the assessment that fine-tuning will result in a
solution.  The standard Sieve of Erathothenes approach is _not
possible_ on standard computers due to the memory requirement estimate
that eryksun has presented.  The point of some of the problems on
Project Euler is to create scenarios where you must be aware of what's
computationally doable in a reasonable amount of resources.  Problem 3
is precisely one of those situations where certain approaches will
fail because those approaches don't respect physical reality enough.
:P

From keithwins at gmail.com  Tue Jan  7 22:22:15 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 7 Jan 2014 16:22:15 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
Message-ID: <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>

um, I used his code, slightly fine-tuned it, and got the solution.... in
.35 seconds (running time, not fine-tuning time ;). On my dinky old
notebook. So I'm inclined to believe it is possible... Though perhaps my
sense of what "fine-tuning" entails doesn't mesh with yours... spoiler
alert, more below.














Note that his code doesn't really (need to) create a sieve of Eratosthenes
all the way to n, but only to sqrt(n). It then tests for divisibility.
Though it is in this that some of the problems lie with the original code.
I'm happy to share my revision with anyone that wants it. It is pretty
rough, consistent with my Python (and math!) skills... it's really quite
close to his code.

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/9eae3044/attachment.html>

From dyoo at hashcollision.org  Tue Jan  7 22:32:51 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 7 Jan 2014 13:32:51 -0800
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
Message-ID: <CAGZAPF5vzmZ46kGVpSJsAbMwDUSOdHNtxc4CdBFoQFNvz+whaQ@mail.gmail.com>

Hi Keith,

Ah, good point.  I did not realize that we could use a sqrt() to get a
good upper bound on what primes we can consider.  That cuts down on
the size of the search space enormously.  Ok, I take my objection back
then.

(That being said, I'm fairly certain that this problem can be solved
in constant space, without maintaining an explicit sieve.)

From keithwins at gmail.com  Tue Jan  7 23:22:38 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 7 Jan 2014 17:22:38 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
Message-ID: <CAO5ffbY30S36nD6OevS+Hr5WsVPzbcMEm3iF+9K6qy-7bSuLQQ@mail.gmail.com>

In fact, I just used it to solve a number 3 orders of magnitude larger than
600851475143, the number from prob 3. It took 12s. I hardly dare go further
than that... I'm not arguing that there's a big list being built in there...

Oops, I dared. 5 orders of magnitude bigger crashes my machine.

Oops oops, it finished. It says it took 161 seconds, but in fact it sort of
half-crashed my machine for the last 30 minutes...

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/691fda14/attachment.html>

From keithwins at gmail.com  Tue Jan  7 23:45:49 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 7 Jan 2014 17:45:49 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAO5ffbY30S36nD6OevS+Hr5WsVPzbcMEm3iF+9K6qy-7bSuLQQ@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
 <CAO5ffbY30S36nD6OevS+Hr5WsVPzbcMEm3iF+9K6qy-7bSuLQQ@mail.gmail.com>
Message-ID: <CAO5ffbb7cj7YBRg=xpsfJooBKOz-syc4Zt06o3padF08xMpAFQ@mail.gmail.com>

Hey Danny,

I think you could use the same sqrt(n) on your algorithm to reduce the
search space. I think you could also increment n += 2 to skip even numbers,
the simplest of sieves.

I think the sieve concept is based on the idea that adding is much less
intensive than dividing, so creating the sieve is fairly quick compared to
all those divides. that said, I might put a timer on your algorithm and
compare them!

Oops: I just did it. Yours won, .23s to .34s. What's more, on certain prime
numbers (with large factors), mine breaks. well never mind then. I'm
blaming Jorge.

Dammit: I forgot to include the i += 2 suggestion I made in the above test
(one also has to start i at 3, hopefully obviously). That improves your
time to .11s. Poor Jorge.

Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/260b3369/attachment.html>

From keithwins at gmail.com  Wed Jan  8 00:15:06 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 7 Jan 2014 18:15:06 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAO5ffbb7cj7YBRg=xpsfJooBKOz-syc4Zt06o3padF08xMpAFQ@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
 <CAO5ffbY30S36nD6OevS+Hr5WsVPzbcMEm3iF+9K6qy-7bSuLQQ@mail.gmail.com>
 <CAO5ffbb7cj7YBRg=xpsfJooBKOz-syc4Zt06o3padF08xMpAFQ@mail.gmail.com>
Message-ID: <CAO5ffba8EoPEwAJCYAb536CW8zmhU536eJ6r_e+vYocQcuv-4w@mail.gmail.com>

On Tue, Jan 7, 2014 at 5:45 PM, Keith Winston <keithwins at gmail.com> wrote:

> Hey Danny,
>
> I think you could use the same sqrt(n) on your algorithm to reduce the
> search space. I think you could also increment n += 2 to skip even numbers,
> the simplest of sieves.
>
> I think the sieve concept is based on the idea that adding is much less
> intensive than dividing, so creating the sieve is fairly quick compared to
> all those divides. that said, I might put a timer on your algorithm and
> compare them!
>
> Oops: I just did it. Yours won, .23s to .34s. What's more, on certain
> prime numbers (with large factors), mine breaks. well never mind then. I'm
> blaming Jorge.
>
> Dammit: I forgot to include the i += 2 suggestion I made in the above test
> (one also has to start i at 3, hopefully obviously). That improves your
> time to .11s. Poor Jorge.
>
> Keith
>
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/49a5f68a/attachment.html>

From keithwins at gmail.com  Wed Jan  8 00:18:04 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 7 Jan 2014 18:18:04 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAO5ffba8EoPEwAJCYAb536CW8zmhU536eJ6r_e+vYocQcuv-4w@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
 <CAO5ffbY30S36nD6OevS+Hr5WsVPzbcMEm3iF+9K6qy-7bSuLQQ@mail.gmail.com>
 <CAO5ffbb7cj7YBRg=xpsfJooBKOz-syc4Zt06o3padF08xMpAFQ@mail.gmail.com>
 <CAO5ffba8EoPEwAJCYAb536CW8zmhU536eJ6r_e+vYocQcuv-4w@mail.gmail.com>
Message-ID: <CAO5ffbb91tyi=3qi6X7bZAvV6WAVt3-ZpN5pOxH0eyRrbvjZSg@mail.gmail.com>

Sorry for the blank message.

I was just going to say that I fixed my version of Eratosthenes' algorithm,
but Danny's is still faster in all cases.

Also, Jorge: I hope it's obvious that I'm kidding around, I wouldn't want
you to feel uncomfortable with asking your questions just because I'm being
goofy.

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/fc6d9ab7/attachment-0001.html>

From dyoo at hashcollision.org  Wed Jan  8 01:09:15 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 7 Jan 2014 16:09:15 -0800
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAO5ffbb91tyi=3qi6X7bZAvV6WAVt3-ZpN5pOxH0eyRrbvjZSg@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
 <CAO5ffbY30S36nD6OevS+Hr5WsVPzbcMEm3iF+9K6qy-7bSuLQQ@mail.gmail.com>
 <CAO5ffbb7cj7YBRg=xpsfJooBKOz-syc4Zt06o3padF08xMpAFQ@mail.gmail.com>
 <CAO5ffba8EoPEwAJCYAb536CW8zmhU536eJ6r_e+vYocQcuv-4w@mail.gmail.com>
 <CAO5ffbb91tyi=3qi6X7bZAvV6WAVt3-ZpN5pOxH0eyRrbvjZSg@mail.gmail.com>
Message-ID: <CAGZAPF6LHz+yqSjyXbB_NZfUDSesfn8ECJQiX+P-NXWgsorOFA@mail.gmail.com>

For reference, Keith's referring to a solution I wrote up and sent to
him privately.  The solution is on a private gist.github.com, since I
want to avoid posting complete Project Euler solutions on a public
forum.  If you're interested, you can email me privately.


Be well!

From alan.gauld at btinternet.com  Wed Jan  8 01:17:46 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 08 Jan 2014 00:17:46 +0000
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
Message-ID: <lai5eu$ihu$1@ger.gmane.org>

On 07/01/14 21:22, Keith Winston wrote:

> Note that his code doesn't really (need to) create a sieve of
> Eratosthenes all the way to n, but only to sqrt(n). It then tests for
> divisibility.

I'm not sure what you mean here.
His algorithm was using an array of booleans to indicate whether a 
number was prime. How does building a list up to sqrt(n) identify primes 
above sqrt(n)?

For example if n is 100 how do you detect that 97 is prime
if you only build a sieve up to 10?

I know you can find the highest prime factor without finding all the 
primes themselves but that's exactly the kind of alternative algorithm 
Euler is looking for. But then it's no longer using Jorge's algorithm, 
which is to test all numbers for primeness then find the highest one 
that is a factor of n, is it?

Ah, OK a light bulb just went on. Amazing what happens when you start 
typing your thoughts! What you mean is to build a seive to identify all 
primes up to sqrt(n) and then test those primes as factors. I had 
thought you intended testing *all* numbers up to sqrt(n) then seeing if 
they were prime. Quite different...

As you say, it's maybe a matter of defining 'tuning' versus creating
an entirely new algorithm! ;-)

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From christian.h.alexander at gmail.com  Tue Jan  7 23:30:29 2014
From: christian.h.alexander at gmail.com (Christian Alexander)
Date: Tue, 7 Jan 2014 17:30:29 -0500
Subject: [Tutor] python 3.3 split method confusion
In-Reply-To: <CAGZAPF57y3XfqOHR=+ZK4HXfdFFthzQ9RvEfuQWAgKmvFYdKew@mail.gmail.com>
References: <CABSj3_7kbrV9ExjAR-vH4atUm+hnq0gYJXauZ=wZk+FqXnNeeA@mail.gmail.com>
 <la95k3$r0i$1@ger.gmane.org>
 <CABSj3_5+0cGEUh3yNfDTM4=aegwYDygh87iBAWgUDjFXSJpTFw@mail.gmail.com>
 <CAGZAPF57y3XfqOHR=+ZK4HXfdFFthzQ9RvEfuQWAgKmvFYdKew@mail.gmail.com>
Message-ID: <CABSj3_47CkXQ_RHmNhAyeUEfxRg5b6GHn2=bfQtqRFpiDaKpEw@mail.gmail.com>

That makes total sense now.  I was  just curious as to why it didn't output
the arbitrary delimiter in the list, or if there was a specific reason for
it.


On Sat, Jan 4, 2014 at 10:03 PM, Danny Yoo <dyoo at hashcollision.org> wrote:

> One of the common cases for split() is to break a line into a list of
> words, for example.
>
> #####################################
> >>> 'hello this is a test'.split()
> ['hello', 'this', 'is', 'a', 'test']
> #####################################
>
> The Standard Library can not do everything that we can conceive of as
> being useful, because that set is fairly large.
>
> If the Standard Library doesn't do it, we'll probably need to do it
> ourselves, or find someone who has done it already.
>
>
> ##########################################
> >>> def mysplit(s, delim):
> ...     start = 0
> ...     while True:
> ...         index = s.find(delim, start)
> ...         if index != -1:
> ...             yield s[start:index]
> ...             yield delim
> ...             start = index + len(delim)
> ...         else:
> ...             yield s[start:]
> ...             return
> ...
> >>> list(mysplit("this,is,a,test", ","))
> ['this', ',', 'is', ',', 'a', ',', 'test']
> ##########################################
>



-- 
Regards,

Christian Alexander
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/885d5c7f/attachment.html>

From keithwins at gmail.com  Wed Jan  8 02:34:07 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 7 Jan 2014 20:34:07 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <lai5eu$ihu$1@ger.gmane.org>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
 <lai5eu$ihu$1@ger.gmane.org>
Message-ID: <CAO5ffba4+YxSVswWxqwrkyyui1puakDrufkdckp2PHN3BY_8XA@mail.gmail.com>

oops, I'm sorry I didn't realize Danny's message to me was private, but
you're right that's better than publishing this right out.

Also: although the sqrt(n) algorithm worked to solve the problem, it isn't
actually correct. There are cases in which it will fail, many in fact.
Oops. One would need to take the Sieve all the way up to n/m for it to work
in this simple version, where m is the lowest prime factor of the number
(which this algorithm WILL always find). There's a nice recursive version
in there somewhere.

Keith



On Tue, Jan 7, 2014 at 7:17 PM, Alan Gauld <alan.gauld at btinternet.com>wrote:

> On 07/01/14 21:22, Keith Winston wrote:
>
>  Note that his code doesn't really (need to) create a sieve of
>> Eratosthenes all the way to n, but only to sqrt(n). It then tests for
>> divisibility.
>>
>
> I'm not sure what you mean here.
> His algorithm was using an array of booleans to indicate whether a number
> was prime. How does building a list up to sqrt(n) identify primes above
> sqrt(n)?
>
> For example if n is 100 how do you detect that 97 is prime
> if you only build a sieve up to 10?
>
> I know you can find the highest prime factor without finding all the
> primes themselves but that's exactly the kind of alternative algorithm
> Euler is looking for. But then it's no longer using Jorge's algorithm,
> which is to test all numbers for primeness then find the highest one that
> is a factor of n, is it?
>
> Ah, OK a light bulb just went on. Amazing what happens when you start
> typing your thoughts! What you mean is to build a seive to identify all
> primes up to sqrt(n) and then test those primes as factors. I had thought
> you intended testing *all* numbers up to sqrt(n) then seeing if they were
> prime. Quite different...
>
> As you say, it's maybe a matter of defining 'tuning' versus creating
> an entirely new algorithm! ;-)
>
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> 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
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/d327983e/attachment.html>

From steve at pearwood.info  Wed Jan  8 02:57:57 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 8 Jan 2014 12:57:57 +1100
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAGZAPF5vzmZ46kGVpSJsAbMwDUSOdHNtxc4CdBFoQFNvz+whaQ@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
 <CAGZAPF5vzmZ46kGVpSJsAbMwDUSOdHNtxc4CdBFoQFNvz+whaQ@mail.gmail.com>
Message-ID: <20140108015756.GM29356@ando>

On Tue, Jan 07, 2014 at 01:32:51PM -0800, Danny Yoo wrote:
> Hi Keith,
> 
> Ah, good point.  I did not realize that we could use a sqrt() to get a
> good upper bound on what primes we can consider.  That cuts down on
> the size of the search space enormously.  Ok, I take my objection back
> then.
> 
> (That being said, I'm fairly certain that this problem can be solved
> in constant space, without maintaining an explicit sieve.)


If you are interested in a range of algorithms for calculating primes, 
you might like to check out this:

https://pypi.python.org/pypi/pyprimes/0.1


Some of the file is a bit clunky, with a few design decisions I'm not 
sure I would still go with today, but the basic algorithms are still 
strong. Even on my clunk old PC with 1GB of RAM, performance is 
reasonable. This is using Python 2.7:

py> import pyprimes
py> with Stopwatch():
...     pyprimes.factors(600851475143)
...
[71, 839, 1471, 6857L]
elapsed time is very small; consider using timeit.Timer for 
micro-timings of small code snippets
time taken: 0.000825 seconds


And if you want all the prime numbers:

py> with Stopwatch():
...     primes = list(pyprimes.primes_below(50000000))
...
time taken: 44.911147 seconds
py> len(primes)
3001134
py> primes[:5]
[2, 3, 5, 7, 11]
py> primes[-5:]
[49999883, 49999897, 49999903, 49999921, 49999991]


That doesn't beat any speed records, especially not on my computer, but 
I have a few ideas for speeding it up and will come back to it some day.


(The call to Stopwatch is a utility function I use to time blocks of 
code. If anyone is interested in the code, let me know.)


-- 
Steven

From keithwins at gmail.com  Wed Jan  8 04:36:56 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 7 Jan 2014 22:36:56 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <20140108015756.GM29356@ando>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
 <CAGZAPF5vzmZ46kGVpSJsAbMwDUSOdHNtxc4CdBFoQFNvz+whaQ@mail.gmail.com>
 <20140108015756.GM29356@ando>
Message-ID: <CAO5ffbZmCSD7eTntsg9002nGKMHtAnVMigpGK5ND1Y71jmthTA@mail.gmail.com>

Hey Steven,

That's a cool primes module, I'm going to look that over more carefully. I
can see that you've thought through this stuff before ;)

And yeah, I'd like to see your Stopwatch code... I haven't looked at "with"
yet, that's interesting. As usual, I don't totally get it...

Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/b03b637c/attachment.html>

From keithwins at gmail.com  Wed Jan  8 04:39:04 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 7 Jan 2014 22:39:04 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAO5ffbZmCSD7eTntsg9002nGKMHtAnVMigpGK5ND1Y71jmthTA@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
 <CAGZAPF5vzmZ46kGVpSJsAbMwDUSOdHNtxc4CdBFoQFNvz+whaQ@mail.gmail.com>
 <20140108015756.GM29356@ando>
 <CAO5ffbZmCSD7eTntsg9002nGKMHtAnVMigpGK5ND1Y71jmthTA@mail.gmail.com>
Message-ID: <CAO5ffbZkH29zoHQW2Yj-RsUpQCOwyzh2yEr+jgxtA_evCQ2FZg@mail.gmail.com>

I'm also happy to note that the sieve I adapted from Jorge generates a list
of primes the same length as yours, which would seem to imply it's correct,
and in 33s, though since it's timed by a different mechanism that may not
mean anything...


On Tue, Jan 7, 2014 at 10:36 PM, Keith Winston <keithwins at gmail.com> wrote:

> Hey Steven,
>
> That's a cool primes module, I'm going to look that over more carefully. I
> can see that you've thought through this stuff before ;)
>
> And yeah, I'd like to see your Stopwatch code... I haven't looked at
> "with" yet, that's interesting. As usual, I don't totally get it...
>
> Keith
>



-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/3ab5efa6/attachment.html>

From keithwins at gmail.com  Wed Jan  8 05:41:53 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 7 Jan 2014 23:41:53 -0500
Subject: [Tutor] garbage collecting
Message-ID: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>

Iirc, Python periodically cleans memory of bits & pieces that are no longer
being used. I periodically do something stupid -- I mean experimental --
and end up with a semi-locked up system. Sometimes it comes back,
sometimes everything after that point runs very slowly, etc.

I just saw where I could do os.system('python'), but in restarting the
interpreter I'd lose everything currently loaded: my real question involves
merely pushing the garbage collector into action, I think.

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140107/8466d931/attachment.html>

From breamoreboy at yahoo.co.uk  Wed Jan  8 09:15:43 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 08 Jan 2014 08:15:43 +0000
Subject: [Tutor] garbage collecting
In-Reply-To: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
Message-ID: <laj1fc$i5h$1@ger.gmane.org>

On 08/01/2014 04:41, Keith Winston wrote:
> Iirc, Python periodically cleans memory of bits & pieces that are no
> longer being used. I periodically do something stupid -- I mean
> experimental -- and end up with a semi-locked up system. Sometimes it
> comes back,  sometimes everything after that point runs very slowly, etc.
>
> I just saw where I could do os.system('python'), but in restarting the
> interpreter I'd lose everything currently loaded: my real question
> involves merely pushing the garbage collector into action, I think.
>
> --
> Keith
>

I've never played with the garbage collector in 10+ years of using 
Pythom, so I think it unlikely you need it now.  Far more likely is that 
you've written an infinite loop, fix that and all other problems go 
away.  Also where would you call the GC?  Surely until you know where in 
your code the problem is, you don't know where to make the call.  Even 
then, if memory is being allocated and Python thinks it's still in use, 
calling the GC won't have any impact anyway.

-- 
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 Jan  8 09:22:02 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 08 Jan 2014 08:22:02 +0000
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAO5ffbZmCSD7eTntsg9002nGKMHtAnVMigpGK5ND1Y71jmthTA@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
 <CAGZAPF5vzmZ46kGVpSJsAbMwDUSOdHNtxc4CdBFoQFNvz+whaQ@mail.gmail.com>
 <20140108015756.GM29356@ando>
 <CAO5ffbZmCSD7eTntsg9002nGKMHtAnVMigpGK5ND1Y71jmthTA@mail.gmail.com>
Message-ID: <laj1r7$mn8$1@ger.gmane.org>

On 08/01/2014 03:36, Keith Winston wrote:
> Hey Steven,
>
> That's a cool primes module, I'm going to look that over more carefully.
> I can see that you've thought through this stuff before ;)
>
> And yeah, I'd like to see your Stopwatch code... I haven't looked at
> "with" yet, that's interesting. As usual, I don't totally get it...
>
> Keith
>

Search for python context managers, then read to your hearts's content :)

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

Mark Lawrence


From __peter__ at web.de  Wed Jan  8 09:56:31 2014
From: __peter__ at web.de (Peter Otten)
Date: Wed, 08 Jan 2014 09:56:31 +0100
Subject: [Tutor] python 3.3 split method confusion
References: <CABSj3_7kbrV9ExjAR-vH4atUm+hnq0gYJXauZ=wZk+FqXnNeeA@mail.gmail.com>
 <la95k3$r0i$1@ger.gmane.org>
 <CABSj3_5+0cGEUh3yNfDTM4=aegwYDygh87iBAWgUDjFXSJpTFw@mail.gmail.com>
 <CAGZAPF57y3XfqOHR=+ZK4HXfdFFthzQ9RvEfuQWAgKmvFYdKew@mail.gmail.com>
Message-ID: <laj3pu$ejs$1@ger.gmane.org>

Danny Yoo wrote:

> One of the common cases for split() is to break a line into a list of
> words, for example.
> 
> #####################################
>>>> 'hello this is a test'.split()
> ['hello', 'this', 'is', 'a', 'test']
> #####################################
> 
> The Standard Library can not do everything that we can conceive of as
> being useful, because that set is fairly large.
> 
> If the Standard Library doesn't do it, we'll probably need to do it
> ourselves, or find someone who has done it already.
> 
> 
> ##########################################
>>>> def mysplit(s, delim):
> ...     start = 0
> ...     while True:
> ...         index = s.find(delim, start)
> ...         if index != -1:
> ...             yield s[start:index]
> ...             yield delim
> ...             start = index + len(delim)
> ...         else:
> ...             yield s[start:]
> ...             return
> ...
>>>> list(mysplit("this,is,a,test", ","))
> ['this', ',', 'is', ',', 'a', ',', 'test']
> ##########################################

The standard library does provide a way to split a string and preserve the 
delimiters:

>>> import re
>>> re.split("(,)", "this,is,a,test")
['this', ',', 'is', ',', 'a', ',', 'test']

It is very flexible...

>>> re.split("([-+*/])", "alpha*beta/gamma-delta")
['alpha', '*', 'beta', '/', 'gamma', '-', 'delta']

but you need to learn a mini-language called "regular expressions" and it 
takes some time to get used to them and to avoid the pitfalls (try to swap 
the "-" and "+" in my second example).


From keithwins at gmail.com  Wed Jan  8 10:30:00 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 8 Jan 2014 04:30:00 -0500
Subject: [Tutor] garbage collecting
In-Reply-To: <laj1fc$i5h$1@ger.gmane.org>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org>
Message-ID: <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>

well, fair enough. Generally, the issue involves instances when Python will
come back, but it might take several minutes or much longer. And weird
behaviour ensues: like timers I put on the program don't actually time the
amount of time it's busy (by a very, very large margin). Also, often
several minutes after such a thing (sometimes quite a bit later), things
will suddenly start working quickly again. Also, on my laptop I can
actually tell when it's struggling, b/c the fan turns on and/or speeds up,
and in many of  these cases it will go into all-out mode, even though I'm
not doing anything. But your point about having no lever with which to move
the world is a good one.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/335ccada/attachment-0001.html>

From breamoreboy at yahoo.co.uk  Wed Jan  8 10:39:20 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 08 Jan 2014 09:39:20 +0000
Subject: [Tutor] garbage collecting
In-Reply-To: <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org>
 <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>
Message-ID: <laj6c6$blk$1@ger.gmane.org>

On 08/01/2014 09:30, Keith Winston wrote:
> well, fair enough. Generally, the issue involves instances when Python
> will come back, but it might take several minutes or much longer. And
> weird behaviour ensues: like timers I put on the program don't actually
> time the amount of time it's busy (by a very, very large margin). Also,
> often several minutes after such a thing (sometimes quite a bit later),
> things will suddenly start working quickly again. Also, on my laptop I
> can actually tell when it's struggling, b/c the fan turns on and/or
> speeds up, and in many of  these cases it will go into all-out mode,
> even though I'm not doing anything. But your point about having no lever
> with which to move the world is a good one.
>

Typical symptoms of hammering a system particularly when you start 
swapping memory to and from disk.  The usual solution is to find a 
better algorithm or buy more ram :)

A slight aside you've managed to lose all of my context, more problems 
with gmail I take it?

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

Mark Lawrence


From keithwins at gmail.com  Wed Jan  8 10:41:51 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 8 Jan 2014 04:41:51 -0500
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <laj1r7$mn8$1@ger.gmane.org>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
 <CAGZAPF5vzmZ46kGVpSJsAbMwDUSOdHNtxc4CdBFoQFNvz+whaQ@mail.gmail.com>
 <20140108015756.GM29356@ando>
 <CAO5ffbZmCSD7eTntsg9002nGKMHtAnVMigpGK5ND1Y71jmthTA@mail.gmail.com>
 <laj1r7$mn8$1@ger.gmane.org>
Message-ID: <CAO5ffbYzMbUk9o9qj3kzqh9OqUz-oit1cj2wshpsiOLt+Oa-RQ@mail.gmail.com>

Yes, I did read the context manager stuff, but I can only absorb a bit of
it, I just don't have the background. It's getting better though. Plus I
think most things will come only after I play with them, and I haven't
really played much with wrappers, decorators and the like. Which is fine,
the year is young. I've just knocked off the first 11 Euler project
problems, which forced me to do a bunch of things for the first time
(mostly quite uglily).

Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/20327549/attachment.html>

From alan.gauld at btinternet.com  Wed Jan  8 11:41:44 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 08 Jan 2014 10:41:44 +0000
Subject: [Tutor] garbage collecting
In-Reply-To: <laj1fc$i5h$1@ger.gmane.org>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org>
Message-ID: <laja0s$ngq$1@ger.gmane.org>

On 08/01/14 08:15, Mark Lawrence wrote:

>> I just saw where I could do os.system('python'), but in restarting the
>> interpreter I'd lose everything currently loaded: my real question
>> involves merely pushing the garbage collector into action, I think.

Don't do that!
You are not restarting the interpreter you are starting a brand new 
interpreter *in addition* to the one that's already running. Now you 
have even less resources to play with. It will make things worse not better.

os.system() is really for running shell commands that hopefully don't 
take long, do a job that doesn't need any input and produces output that 
you don't need to process(or a file that you can). Printing
a file, converting a file with lame of ffmpeg, say, that kind of thing.
It's actually deprecated now anyway and the subprocess module is preferred.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From breamoreboy at yahoo.co.uk  Wed Jan  8 11:50:42 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 08 Jan 2014 10:50:42 +0000
Subject: [Tutor] garbage collecting
In-Reply-To: <laja0s$ngq$1@ger.gmane.org>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org> <laja0s$ngq$1@ger.gmane.org>
Message-ID: <lajahv$t5r$1@ger.gmane.org>

On 08/01/2014 10:41, Alan Gauld wrote:
> On 08/01/14 08:15, Mark Lawrence wrote:

Did I? :)

>
>>> I just saw where I could do os.system('python'), but in restarting the
>>> interpreter I'd lose everything currently loaded: my real question
>>> involves merely pushing the garbage collector into action, I think.
>
> Don't do that!
> You are not restarting the interpreter you are starting a brand new
> interpreter *in addition* to the one that's already running. Now you
> have even less resources to play with. It will make things worse not
> better.
>
> os.system() is really for running shell commands that hopefully don't
> take long, do a job that doesn't need any input and produces output that
> you don't need to process(or a file that you can). Printing
> a file, converting a file with lame of ffmpeg, say, that kind of thing.
> It's actually deprecated now anyway and the subprocess module is preferred.
>


-- 
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 Jan  8 12:18:22 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 8 Jan 2014 22:18:22 +1100
Subject: [Tutor] garbage collecting
In-Reply-To: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
Message-ID: <20140108111821.GP29356@ando>

On Tue, Jan 07, 2014 at 11:41:53PM -0500, Keith Winston wrote:
> Iirc, Python periodically cleans memory of bits & pieces that are no longer
> being used. I periodically do something stupid -- I mean experimental --
> and end up with a semi-locked up system. Sometimes it comes back,
> sometimes everything after that point runs very slowly, etc.

You can control the garbage collector with the gc module, but you 
shouldn't have to. It runs automatically, whenever your code is done 
with an object, the garbage collector reclaims the memory used. In 
particular, the garbage collector is not the solution to your problem.

As Mark says, the symptoms you describe suggest you have run out of 
memory and are hammering the swap space. This will slow everything 
down by a lot. Virtual memory is *millions* of times slower than real 
memory (RAM).

None of this is specific to Python, but here's a quick (and simplified) 
explanation, as best I understand it myself. Modern operating systems, 
which include Windows, Linux and OS X, have a concept of "virtual 
memory", which you can consider to be a great big file on your hard 
disk. (To be pedantic, it's a single file in Windows, usually a separate 
partition on Linux, and I don't know about OS X.) When an application 
requests some memory, if there is not enough memory available, the OS 
will grab some chunk of memory which is not in use (we'll call it "B"), 
copy it to the swap file (the virtual memory), then free it up for the 
application to use. Then when the app tries to use memory B back again, 
the OS sees that it's in swap, grab another chunk of real memory, copy 
it to swap, then move memory B back into RAM.

So think of virtual memory (swap space) as a great big cheap but 
astonishingly slow storage area. When you run out of space in RAM, stuff 
gets copied to swap. When you try to use that stuff in swap, something 
else has to get moved to swap first, to free up space in RAM to move the 
first chunk back into RAM. The OS is always doing this, and you hardly 
ever notice.

Except, when an app asks for a lot of memory, or lots and lots and lots 
of apps ask for a little bit all at the same time, you can end up with a 
situtation where the OS is spending nearly all its time just copying 
stuff from RAM to swap and back again. So much time is being spent doing 
this that the application itself hardly gets any time to run, and so 
everything slows down to a crawl. You can often actually *hear this 
happening*, as the hard drive goes nuts jumping backwards and forwards 
copying data to and fro swap. This is called "thrashing", and it isn't 
fun for anyone.

The only cure for a thrashing system is to sit back and wait, possibly 
shut down a few applications (which may temporarily make the thrashing 
worse!) and eventually the whole thing will settle down again, in five 
minutes or five days.

I'm not exaggerating -- I once made a mistake with a list, ran 
something stupid like mylist = [None]*(10**9), and my system was 
thrashing so hard the operating system stopped responding. I left it for 
16 hours and it was still thrashing, so I shut the power off. That's a 
fairly extreme example though, normally a thrashing system won't be 
*that* unresponsive, it will just be slow.

If you are using Linux, you can use the ulimit command to limit how much 
memory the OS will allow an application to use before shutting it off. 
So for example:

[steve at ando ~]$ ulimit -v 10000
[steve at ando ~]$ python
Python 2.7.2 (default, May 18 2012, 18:25:10)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-52)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> l = range(200000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError



> I just saw where I could do os.system('python'), but in restarting the
> interpreter I'd lose everything currently loaded: my real question involves
> merely pushing the garbage collector into action, I think.

As Alan has said, os.system('python') doesn't restart the interpreter, 
it pauses it and starts up a new one.



-- 
Steven

From alan.gauld at btinternet.com  Wed Jan  8 12:26:20 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 08 Jan 2014 11:26:20 +0000
Subject: [Tutor] garbage collecting
In-Reply-To: <lajahv$t5r$1@ger.gmane.org>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org> <laja0s$ngq$1@ger.gmane.org>
 <lajahv$t5r$1@ger.gmane.org>
Message-ID: <lajckg$mh6$1@ger.gmane.org>

On 08/01/14 10:50, Mark Lawrence wrote:
> On 08/01/2014 10:41, Alan Gauld wrote:
>> On 08/01/14 08:15, Mark Lawrence wrote:
>
> Did I? :)

Oops, one too many lines deleted.
Sorry Mark.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From steve at pearwood.info  Wed Jan  8 12:41:53 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 8 Jan 2014 22:41:53 +1100
Subject: [Tutor] OverflowError: cannot fit 'long' into an index-sized
	integer
In-Reply-To: <CAO5ffbZmCSD7eTntsg9002nGKMHtAnVMigpGK5ND1Y71jmthTA@mail.gmail.com>
References: <CAG3CVWjKykxSODqPZvymWU8SCz5iHSP2-RT+Oa6jAiL2jfmKDA@mail.gmail.com>
 <CACL+1au_WhzHFm-9CTQqycecfuxDSN4KHtHyO8Fi=zRjALoHgQ@mail.gmail.com>
 <CAGZAPF4sGxHNz9eazqe6vAwFTzx1fabs__2BnBcAk2wfnOhW+w@mail.gmail.com>
 <CAO5ffbY+Oq964DcJbDnGv6U-nCN-fJeW_ujNH+hvV=DN=3Df1g@mail.gmail.com>
 <CAGZAPF7wx3=pEP_r8+W6rW0cnsvRUa3otRCQN8qrEJmG9SeEyQ@mail.gmail.com>
 <CAO5ffbaS-cFA082uZ5iPtAVmyk3ASiRE9ZsOyZSih4YYkxMJRw@mail.gmail.com>
 <CAGZAPF5vzmZ46kGVpSJsAbMwDUSOdHNtxc4CdBFoQFNvz+whaQ@mail.gmail.com>
 <20140108015756.GM29356@ando>
 <CAO5ffbZmCSD7eTntsg9002nGKMHtAnVMigpGK5ND1Y71jmthTA@mail.gmail.com>
Message-ID: <20140108114152.GQ29356@ando>

On Tue, Jan 07, 2014 at 10:36:56PM -0500, Keith Winston wrote:
> And yeah, I'd like to see your Stopwatch code... I haven't looked at "with"
> yet, that's interesting. As usual, I don't totally get it...

Okay, let's talk about a common pattern in Python code:

try:
    do some stuff
finally:
    clean up

You have a "try" block which runs some code. Whatever happens inside the 
block, regardless of whether it succeeds or fails, when it is done, 
Python runs the "finally" block. Let's see this in action, first with a 
successful computation, then an unsuccessful one:


py> try:
...     print(1 + 1)
... finally:
...     print("=== Done ===")
...
2
=== Done ===

py> try:
...     print(1 + "1")
... finally:
...     print("=== Done ===")
...
=== Done ===
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'


This is such a common pattern, that a few versions back (Python 2.5, I 
believe) Python introduced new syntax for it: context managers and the 
"with" statement.

The new syntax is:

with obj as name:
    block


When Python runs the "with" statement, it expects that obj will have two 
special methods:

    * obj.__enter__ is run when the "with" statement begins, just 
      before the block is run;

    * obj.__exit__ is run when the block exits, regardless of
      whether it exited successfully, or due to an error.


There are more complications, of course, but in a nutshell that's it. A 
with statement is not terribly different from this:


name = obj.__enter__()
try:
    block
finally:
    obj.__exit__(*args)


(The args passed to __exit__ have to do with any exceptions raised 
inside the block.)



The Stopwatch code is quite simple: it has an __enter__ method which 
starts the timer, and an __exit__ method which stops it and reports how 
long things took.


=== cut ===


import gc
import sys

from functools import wraps


class Stopwatch:
    """Time hefty or long-running block of code using a ``with`` statement:

    >>> with Stopwatch():  #doctest: +SKIP
    ...     do_this()
    ...     do_that()
    ...
    time taken: 1.234567 seconds

    The Stopwatch class takes four optional arguments:

    timer::
        Timer function; by default, the default timer from the
        timeit module is used.

    allow_gc::
        If true (the default), the garbage collector is free to
        operate while the code block is running, otherwise, the
        garbage collector is temporarily disabled.

    verbose::
        If a true value (the default), the timer result is
        reported after the code block completes, and a warning
        displayed if the elapsed time is too small.

    cutoff::
        If None, elapsed time warnings are disabled; otherwise,
        the amount of time in seconds below which a warning is
        displayed. Defaults to 0.001.

    For non-interactive use, you can retrieve the time taken using the
    ``interval`` attribute:

    >>> with Stopwatch(verbose=False) as sw:  #doctest: +SKIP
    ...     do_this()
    ...     do_that()
    ...
    >>> print(sw.interval)  #doctest: +SKIP
    1.234567

    """
    def __init__(self, timer=None, allow_gc=True, verbose=True, cutoff=0.001):
        if timer is None:
            from timeit import default_timer as timer
        self.timer = timer
        self.allow_gc = allow_gc
        self.verbose = verbose
        self.cutoff = cutoff
        self.start = self.end = self.interval = None

    def __enter__(self):
        if not self.allow_gc:
            self._gc_state = gc.isenabled()
            gc.disable()
        self.interval = None
        self.start = self.timer()
        return self

    def __exit__(self, *args):
        self.end = self.timer()
        if not self.allow_gc and self._gc_state:
            gc.enable()
        self.interval = self.end - self.start
        self._report()

    def _report(self):
        if not self.verbose:
            return
        if self.cutoff is not None and self.interval < self.cutoff:
            print("elapsed time is very small; consider using timeit.Timer"
                  " for micro-timings of small code snippets")
        print('time taken: %f seconds' % self.interval)


=== cut ===

And that's all there is to it!



-- 
Steven

From denis.spir at gmail.com  Wed Jan  8 12:43:06 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 08 Jan 2014 12:43:06 +0100
Subject: [Tutor] garbage collecting
In-Reply-To: <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org>
 <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>
Message-ID: <52CD39CA.5030600@gmail.com>

On 01/08/2014 10:30 AM, Keith Winston wrote:
> well, fair enough. Generally, the issue involves instances when Python will
> come back, but it might take several minutes or much longer. And weird
> behaviour ensues: like timers I put on the program don't actually time the
> amount of time it's busy (by a very, very large margin). Also, often
> several minutes after such a thing (sometimes quite a bit later), things
> will suddenly start working quickly again. Also, on my laptop I can
> actually tell when it's struggling, b/c the fan turns on and/or speeds up,
> and in many of  these cases it will go into all-out mode, even though I'm
> not doing anything. But your point about having no lever with which to move
> the world is a good one.

It smells like a logical bug, or lack of simplicity / clarity, leading to a 
behaviour with "exponential" cost (in cpu usage, thus time, more or less in 
proportion), in some given circumstances. Or maybe just an unavoidable 
exponential cost routine, but the quantity of iput shoulde remain small, while 
in some (buggy) cases it is big.

[Just wildly guessing, don't know your app & code. Can you reduce it to a 
minimal still manifesting similar bug?]

Denis

From steve at pearwood.info  Wed Jan  8 13:36:51 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 8 Jan 2014 23:36:51 +1100
Subject: [Tutor] garbage collecting
In-Reply-To: <52CD39CA.5030600@gmail.com>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org>
 <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>
 <52CD39CA.5030600@gmail.com>
Message-ID: <20140108123651.GR29356@ando>

On Wed, Jan 08, 2014 at 12:43:06PM +0100, spir wrote:

> [Just wildly guessing, don't know your app & code. Can you reduce it to a 
> minimal still manifesting similar bug?]

Try (or rather, *don't* try):

import sys
list(range(sys.maxsize))

That ought to do it :-)


(Note: depending on your operating system, that may simply fail with 
MemoryError, or lock up your computer. Don't blame me for any data loss 
or inconvenience if you try it.)


-- 
Steven

From keithwins at gmail.com  Wed Jan  8 18:47:27 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 8 Jan 2014 12:47:27 -0500
Subject: [Tutor] garbage collecting
In-Reply-To: <20140108123651.GR29356@ando>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org>
 <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>
 <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando>
Message-ID: <CAO5ffbZBZgCO7s9+s0Mh_q6wOPFES2t995kGZe2P+T33rkVb_g@mail.gmail.com>

Well, thanks everyone. I get the picture. And there's nothing subtle going
on here: I'm playing around, trying to factor million-digit numbers and the
like. No biggie, this was interesting.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/cdf24021/attachment-0001.html>

From stareq13 at yahoo.com  Wed Jan  8 19:19:05 2014
From: stareq13 at yahoo.com (S Tareq)
Date: Wed, 8 Jan 2014 18:19:05 +0000 (GMT)
Subject: [Tutor] need help how to run it on python 3.3
Message-ID: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com>

need help how to run it on python 3.3, or change it to python 3.3 when i run it says syntax error if i run it on python 2.7 it works.?


# Import statements
import random
import datetime
#Arrays to store the definitions and keywords read from the file
keywords=[];
definition=[];
correctAnswer=[];
#Counter for the wrong Answer and counter of number of definition in
correctAnswerCounter=0?
wrongAnswer=0;
counter=0;
# Taking User input for accepting the file name to be read
filename= raw_input("Enter the File Name with extension")
#Reading the file from start to the end
for line in open(filename,'r').readlines():
? ? if(counter%2==0):
? ? ? ? keywords.append(line);
? ? ? ? counter=counter+1;
? ? ? ? correctAnswer.append(0)
? ? else:
? ? ? ? definition.append(line);
? ? ? ? keys=[];
? ? ? ? keys=line.split(" ");
? ? ? ? counter=counter+1;
# Running two while loops to make the pattern recursive
while True:
# Starting the time for quiz and also, creating variables to make sure that same sequences and answers are not repeated
? ? a = datetime.datetime.now().replace(microsecond=0)
? ? prevWord=0
? ? prevSeq=0
? ? # While loop to run the code till each answer is correctly answered
? ? while correctAnswer.count(2)!=(counter/2):
? ? ? ? #While loop to generate an different random number from one the generated previously
? ? ? ? while True: ? ? ? ?
? ? ? ? ? ? word=random.randint(0,(counter/2)-1)
? ? ? ? ? ? if(correctAnswer[word]!=2):
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? if(prevWord==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? # Displaying the new keyword each time.
? ? ? ? print "Please Select the number which is the correct definition of the word:" ,keywords[word]
? ? ? ? #Generating an new sequence each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? sequences =random.randint(0,2)
? ? ? ? ? ? if(prevSeq==sequences):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswer=random.randint(0,len(correctAnswer)-1)
? ? ? ? ? ? if(incorrectAnswer==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else :
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer ?each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswerSecond=random.randint(0,len(correctAnswer)-1);
? ? ? ? ? ? if (incorrectAnswer==incorrectAnswerSecond):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? if(incorrectAnswerSecond==word):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? # Displaying the options to the user based on the sequence number generated
? ? ? ? if (sequences==0):
? ? ? ? ? ? print "1.",definition[word]
? ? ? ? ? ? print "2.",definition[incorrectAnswer]
? ? ? ? ? ? print "3.",definition[incorrectAnswerSecond]
? ? ? ? elif (sequences==1):
? ? ? ? ? ? print "1.",definition[incorrectAnswer]
? ? ? ? ? ? print "2.",definition[incorrectAnswerSecond]
? ? ? ? ? ? print "3.",definition[word]
? ? ? ? elif (sequences==2):
? ? ? ? ? ? print "1.",definition[incorrectAnswerSecond]
? ? ? ? ? ? print "2.",definition[word]
? ? ? ? ? ? print "3.",definition[incorrectAnswer]
? ? ? ? #Taking the answer from user
? ? ? ? answer = raw_input("Enter the Correct Number between 1 to 3")
? ? ? ? # Assign the seq and word to preseq and word
? ? ? ? prevSeq=sequences
? ? ? ? prevWord=word
? ? ? ? #Checking the answer if they are corret.
? ? ? ? if(0 == sequences):
? ? ? ? ? ? if(answer == "1"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(1 == sequences):
? ? ? ? ? ? if(answer == "3"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(2 == sequences):
? ? ? ? ? ? if(answer == "2"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1
? ? # Stopping the time of the clock
? ? b = datetime.datetime.now().replace(microsecond=0)
? ? # displaying number of wrong answer and total quiz time
? ? print "Total Number of Wrong Answer:", wrongAnswer
? ? print "Total Quiz Time", (b-a)
? ? print "Total Number of correct Answer", correctAnswerCounter
? ? #asking user to reenter
? ? restart= raw_input("Do You want to start the quiz again Yes or No")
? ? if(restart=="no"):
? ? ? ? print "Thanks for quiz"
? ? ? ? break;
? ? elif(restart=="yes"):
? ? ? ? wrongAnswer=0
? ? ? ? correctAnswerCounter=0;
? ? ? ? correctAnswer=[];
? ? ? ? i=0
? ? ? ? while (i<(counter/2)):
? ? ? ? ? ? i=i+1
? ? ? ? ? ? correctAnswer.append(0)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/7dc2dc84/attachment.html>

From keithwins at gmail.com  Wed Jan  8 21:25:50 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 8 Jan 2014 15:25:50 -0500
Subject: [Tutor] recursion depth
Message-ID: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>

I've been playing with recursion, it's very satisfying.

However, it appears that even if I sys.setrecursionlimit(100000), it blows
up at about 24,000 (appears to reset IDLE). I guess there must be a lot of
overhead with recursion, if only 24k times are killing my memory?

I'm playing with a challenge a friend gave me: add each number, up to 1000,
with it's reverse, continuing the process until you've got a palindrome
number. Then report back the number of iterations it takes. There's one
number, 196, that never returns, so I skip it. It's a perfect place to
practice recursion (I do it in the adding part, and the palindrome checking
part), but apparently I can't help but blow up my machine...

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/0ca96485/attachment.html>

From oscar.j.benjamin at gmail.com  Wed Jan  8 21:30:07 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Wed, 8 Jan 2014 20:30:07 +0000
Subject: [Tutor] garbage collecting
In-Reply-To: <CAO5ffbZBZgCO7s9+s0Mh_q6wOPFES2t995kGZe2P+T33rkVb_g@mail.gmail.com>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org>
 <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>
 <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando>
 <CAO5ffbZBZgCO7s9+s0Mh_q6wOPFES2t995kGZe2P+T33rkVb_g@mail.gmail.com>
Message-ID: <CAHVvXxTg4RVMQ9EPQmqb_eJ+Eb49Vvbw=O=AgJx=++C_nnb6aA@mail.gmail.com>

On Jan 8, 2014 5:51 PM, "Keith Winston" <keithwins at gmail.com> wrote:
>
> Well, thanks everyone. I get the picture. And there's nothing subtle
going on here: I'm playing around, trying to factor million-digit numbers
and the like. No biggie, this was interesting.

Million digit numbers will use up some memory. Perhaps a megabyte per
number. If you just hold one in memory and try to factor it then it
shouldn't lead to the problems you described. Or are you holding a list of
many million digit numbers? Or are they several hundred million digits?

The garbage collector has nothing to do with the memory usage of immutable
types like ints. There are deallocated instantly when the last reference
you hold is cleared (in CPython). So if you run out of memory because of
them then it is because you're keeping them alive in your own code. Running
the garbage collector with gc.collect cannot help with that.

Oscar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/15a93359/attachment-0001.html>

From breamoreboy at yahoo.co.uk  Wed Jan  8 21:42:11 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 08 Jan 2014 20:42:11 +0000
Subject: [Tutor] need help how to run it on python 3.3
In-Reply-To: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com>
References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com>
Message-ID: <lakd71$nge$1@ger.gmane.org>

On 08/01/2014 18:19, S Tareq wrote:
> need help how to run it on python 3.3, or change it to python 3.3 when i
> run it says syntax error if i run it on python 2.7 it works.
>

>      if(counter%2==0):

Please remove those unneeded brackets, this is a Python list, not C :)

>          print "Please Select the number which is the correct definition
> of the word:" ,keywords[word]

Please add the needed brackets, print is a function in Python 3, not a 
statement.

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

Mark Lawrence


From emile at fenx.com  Wed Jan  8 21:42:45 2014
From: emile at fenx.com (Emile van Sebille)
Date: Wed, 08 Jan 2014 12:42:45 -0800
Subject: [Tutor] recursion depth
In-Reply-To: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
Message-ID: <lakd83$nrb$1@ger.gmane.org>

On 1/8/2014 12:25 PM, Keith Winston wrote:
> I've been playing with recursion, it's very satisfying.
>
> However, it appears that even if I sys.setrecursionlimit(100000), it
> blows up at about 24,000 (appears to reset IDLE). I guess there must be
> a lot of overhead with recursion, if only 24k times are killing my memory?

Yes -- the docs warn specifically about that:

sys.setrecursionlimit(limit)?
Set the maximum depth of the Python interpreter stack to limit. This 
limit prevents infinite recursion from causing an overflow of the C 
stack and crashing Python.

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


> I'm playing with a challenge a friend gave me: add each number, up to
> 1000, with it's reverse, continuing the process until you've got a
> palindrome number. Then report back the number of iterations it takes.
> There's one number, 196, that never returns, so I skip it. It's a
> perfect place to practice recursion (I do it in the adding part, and the
> palindrome checking part), but apparently I can't help but blow up my
> machine...

Without seeing your code it's hard to be specific, but it's obvious 
you'll need to rethink your approach.  :)

Emile




From dyoo at hashcollision.org  Wed Jan  8 21:45:54 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Wed, 8 Jan 2014 12:45:54 -0800
Subject: [Tutor] need help how to run it on python 3.3
In-Reply-To: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com>
References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com>
Message-ID: <CAGZAPF6nJ1ZC7b8Y2Brfo9mvUvc8b9qZ5Eee3xGoL+RBx+9PSg@mail.gmail.com>

Hi S Tareq,


You probably want to review the "What's new in Python 3" document,
with close attention to the "Common Stumbing Blocks" section:

    http://docs.python.org/3.0/whatsnew/3.0.html#common-stumbling-blocks

Have you read this document already?

From keithwins at gmail.com  Wed Jan  8 22:09:36 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 8 Jan 2014 16:09:36 -0500
Subject: [Tutor] garbage collecting
In-Reply-To: <CAHVvXxTg4RVMQ9EPQmqb_eJ+Eb49Vvbw=O=AgJx=++C_nnb6aA@mail.gmail.com>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org>
 <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>
 <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando>
 <CAO5ffbZBZgCO7s9+s0Mh_q6wOPFES2t995kGZe2P+T33rkVb_g@mail.gmail.com>
 <CAHVvXxTg4RVMQ9EPQmqb_eJ+Eb49Vvbw=O=AgJx=++C_nnb6aA@mail.gmail.com>
Message-ID: <CAO5ffbZFgxn9duOSK8ibkF0WNVRrGk+UGmsS9R-jMW0DzvwhTA@mail.gmail.com>

On Wed, Jan 8, 2014 at 3:30 PM, Oscar Benjamin
<oscar.j.benjamin at gmail.com>wrote:

> The garbage collector has nothing to do with the memory usage of immutable
> types like ints. There are deallocated instantly when the last reference
> you hold is cleared (in CPython). So if you run out of memory because of
> them then it is because you're keeping them alive in your own code. Running
> the garbage collector with gc.collect cannot help with that.
>

Well that's sort of interesting... so it's different for mutables? huh.
Anyway, I think I got what I can reasonably hope to get from this question,
thanks to you and everyone!

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/81a0c003/attachment.html>

From keithwins at gmail.com  Wed Jan  8 22:11:52 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 8 Jan 2014 16:11:52 -0500
Subject: [Tutor] recursion depth
In-Reply-To: <lakd83$nrb$1@ger.gmane.org>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
 <lakd83$nrb$1@ger.gmane.org>
Message-ID: <CAO5ffbbM2NdEFYP5OSB3syz2sa67RvhZ1LX9SgPT24GgY7faPw@mail.gmail.com>

On Wed, Jan 8, 2014 at 3:42 PM, Emile van Sebille <emile at fenx.com> wrote:

>
> Without seeing your code it's hard to be specific, but it's obvious you'll
> need to rethink your approach.  :)



Yes, it's clear I need to do the bulk of it without recusion, I haven't
really thought about how to do that. I may or may not ever get around to
doing it, since this was primarily an exercise in recursion, for me...
Thanks for your thoughts.

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/5b719fb8/attachment.html>

From oscar.j.benjamin at gmail.com  Wed Jan  8 22:22:50 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Wed, 8 Jan 2014 21:22:50 +0000
Subject: [Tutor] garbage collecting
In-Reply-To: <CAO5ffbZFgxn9duOSK8ibkF0WNVRrGk+UGmsS9R-jMW0DzvwhTA@mail.gmail.com>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org>
 <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>
 <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando>
 <CAO5ffbZBZgCO7s9+s0Mh_q6wOPFES2t995kGZe2P+T33rkVb_g@mail.gmail.com>
 <CAHVvXxTg4RVMQ9EPQmqb_eJ+Eb49Vvbw=O=AgJx=++C_nnb6aA@mail.gmail.com>
 <CAO5ffbZFgxn9duOSK8ibkF0WNVRrGk+UGmsS9R-jMW0DzvwhTA@mail.gmail.com>
Message-ID: <CAHVvXxTqMOAKq6OETBr4jUu284=q3Kpc28OxBNyGofNTrmiDSg@mail.gmail.com>

On Jan 8, 2014 9:11 PM, "Keith Winston" <keithwins at gmail.com> wrote:
>
>
> On Wed, Jan 8, 2014 at 3:30 PM, Oscar Benjamin <oscar.j.benjamin at gmail.com>
wrote:
>>
>> The garbage collector has nothing to do with the memory usage of
immutable types like ints. There are deallocated instantly when the last
reference you hold is cleared (in CPython). So if you run out of memory
because of them then it is because you're keeping them alive in your own
code. Running the garbage collector with gc.collect cannot help with that.
>
>
> Well that's sort of interesting... so it's different for mutables? huh.
Anyway, I think I got what I can reasonably hope to get from this question,
thanks to you and everyone!
>

It's not that it's different for mutables specifically. The primary
deallocation method is by reference count. This fails if there are
reference cycles so CPython has a cyclic garbage collector that deals with
those. Reference cycles can only emerge because of mutable containers.

A slight correction to what I wrote above is that if an immutable object
such as an int is referenced by an mutable one that is itself in a
reference cycle then it wouldn't be deallocated until the cyclic garbage
collector runs.

Oscar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/dcabbe09/attachment-0001.html>

From eryksun at gmail.com  Wed Jan  8 22:23:06 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 8 Jan 2014 16:23:06 -0500
Subject: [Tutor] recursion depth
In-Reply-To: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
Message-ID: <CACL+1auM8YtgNLHBufvJ+W7PX8eCFHbMrpuR732iFGFAYGT-zw@mail.gmail.com>

On Wed, Jan 8, 2014 at 3:25 PM, Keith Winston <keithwins at gmail.com> wrote:
> I've been playing with recursion, it's very satisfying.
>
> However, it appears that even if I sys.setrecursionlimit(100000), it blows
> up at about 24,000 (appears to reset IDLE). I guess there must be a lot of
> overhead with recursion, if only 24k times are killing my memory?

CPython recursion is limited by the thread's stack size, since
evaluating a Python frame requires calling PyEval_EvalFrameEx. The
default stack size on Windows is 1 MiB, and on Linux RLIMIT_STACK is
typically set at 8 MiB (inspect this w/ the stdlib's resource module).

You can create a worker thread with a larger stack using the threading
module. On Windows the upper limit is 256 MiB, so give this a try:

    import sys
    import threading

    MiB = 2 ** 20
    threading.stack_size(256 * MiB)

    sys.setrecursionlimit(100000)

    t = threading.Thread(target=your_function)
    t.start()

I'm not saying this is a good solution in general. It's just something
to play around with, and may help in a pinch.

From smayer69 at me.com  Wed Jan  8 21:28:18 2014
From: smayer69 at me.com (Steve Mayer)
Date: Wed, 08 Jan 2014 12:28:18 -0800
Subject: [Tutor] need help how to run it on python 3.3
In-Reply-To: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com>
References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com>
Message-ID: <249C27FB-94C4-471A-BE56-A96EFC7400A0@me.com>

You might want to check out the '2to3' program to convert Python 2.x 
code to Python 3.x code.

The following command worked to change your code to runnable Python 3.x 
code:

    2to3 -w <your file containing 2.x code>



-- 
Steve Mayer
smayer69 at me.com

On 8 Jan 2014, at 10:19, S Tareq wrote:

> need help how to run it on python 3.3, or change it to python 3.3 when 
> i run it says syntax error if i run it on python 2.7 it works.?
>
>
> # Import statements
> import random
> import datetime
> #Arrays to store the definitions and keywords read from the file
> keywords=[];
> definition=[];
> correctAnswer=[];
> #Counter for the wrong Answer and counter of number of definition in
> correctAnswerCounter=0?
> wrongAnswer=0;
> counter=0;
> # Taking User input for accepting the file name to be read
> filename= raw_input("Enter the File Name with extension")
> #Reading the file from start to the end
> for line in open(filename,'r').readlines():
> ? ? if(counter%2==0):
> ? ? ? ? keywords.append(line);
> ? ? ? ? counter=counter+1;
> ? ? ? ? correctAnswer.append(0)
> ? ? else:
> ? ? ? ? definition.append(line);
> ? ? ? ? keys=[];
> ? ? ? ? keys=line.split(" ");
> ? ? ? ? counter=counter+1;
> # Running two while loops to make the pattern recursive
> while True:
> # Starting the time for quiz and also, creating variables to make sure 
> that same sequences and answers are not repeated
> ? ? a = datetime.datetime.now().replace(microsecond=0)
> ? ? prevWord=0
> ? ? prevSeq=0
> ? ? # While loop to run the code till each answer is correctly 
> answered
> ? ? while correctAnswer.count(2)!=(counter/2):
> ? ? ? ? #While loop to generate an different random number from 
> one the generated previously
> ? ? ? ? while True: ? ? ? ?
> ? ? ? ? ? ? word=random.randint(0,(counter/2)-1)
> ? ? ? ? ? ? if(correctAnswer[word]!=2):
> ? ? ? ? ? ? ? ? break;
> ? ? ? ? ? ? if(prevWord==word):
> ? ? ? ? ? ? ? ? continue;
> ? ? ? ? # Displaying the new keyword each time.
> ? ? ? ? print "Please Select the number which is the correct 
> definition of the word:" ,keywords[word]
> ? ? ? ? #Generating an new sequence each time different from 
> previous one
> ? ? ? ? while True:
> ? ? ? ? ? ? sequences =random.randint(0,2)
> ? ? ? ? ? ? if(prevSeq==sequences):
> ? ? ? ? ? ? ? ? continue;
> ? ? ? ? ? ? else:
> ? ? ? ? ? ? ? ? break
> ? ? ? ? #Generating an new incorrect answer each time different 
> from previous one
> ? ? ? ? while True:
> ? ? ? ? ? ? 
> incorrectAnswer=random.randint(0,len(correctAnswer)-1)
> ? ? ? ? ? ? if(incorrectAnswer==word):
> ? ? ? ? ? ? ? ? continue;
> ? ? ? ? ? ? else :
> ? ? ? ? ? ? ? ? break
> ? ? ? ? #Generating an new incorrect answer ?each time different 
> from previous one
> ? ? ? ? while True:
> ? ? ? ? ? ? 
> incorrectAnswerSecond=random.randint(0,len(correctAnswer)-1);
> ? ? ? ? ? ? if (incorrectAnswer==incorrectAnswerSecond):
> ? ? ? ? ? ? ? ? continue
> ? ? ? ? ? ? if(incorrectAnswerSecond==word):
> ? ? ? ? ? ? ? ? continue
> ? ? ? ? ? ? else:
> ? ? ? ? ? ? ? ? break
> ? ? ? ? # Displaying the options to the user based on the sequence 
> number generated
> ? ? ? ? if (sequences==0):
> ? ? ? ? ? ? print "1.",definition[word]
> ? ? ? ? ? ? print "2.",definition[incorrectAnswer]
> ? ? ? ? ? ? print "3.",definition[incorrectAnswerSecond]
> ? ? ? ? elif (sequences==1):
> ? ? ? ? ? ? print "1.",definition[incorrectAnswer]
> ? ? ? ? ? ? print "2.",definition[incorrectAnswerSecond]
> ? ? ? ? ? ? print "3.",definition[word]
> ? ? ? ? elif (sequences==2):
> ? ? ? ? ? ? print "1.",definition[incorrectAnswerSecond]
> ? ? ? ? ? ? print "2.",definition[word]
> ? ? ? ? ? ? print "3.",definition[incorrectAnswer]
> ? ? ? ? #Taking the answer from user
> ? ? ? ? answer = raw_input("Enter the Correct Number between 1 to 
> 3")
> ? ? ? ? # Assign the seq and word to preseq and word
> ? ? ? ? prevSeq=sequences
> ? ? ? ? prevWord=word
> ? ? ? ? #Checking the answer if they are corret.
> ? ? ? ? if(0 == sequences):
> ? ? ? ? ? ? if(answer == "1"):
> ? ? ? ? ? ? ? ? print "success"
> ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
> ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
> ? ? ? ? ? ? else:
> ? ? ? ? ? ? ? ? print "Wrong Answer"
> ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
> ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
> ? ? ? ? elif(1 == sequences):
> ? ? ? ? ? ? if(answer == "3"):
> ? ? ? ? ? ? ? ? print "success"
> ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
> ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
> ? ? ? ? ? ? else:
> ? ? ? ? ? ? ? ? print "Wrong Answer"
> ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
> ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
> ? ? ? ? elif(2 == sequences):
> ? ? ? ? ? ? if(answer == "2"):
> ? ? ? ? ? ? ? ? print "success"
> ? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
> ? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
> ? ? ? ? ? ? else:
> ? ? ? ? ? ? ? ? print "Wrong Answer"
> ? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
> ? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1
> ? ? # Stopping the time of the clock
> ? ? b = datetime.datetime.now().replace(microsecond=0)
> ? ? # displaying number of wrong answer and total quiz time
> ? ? print "Total Number of Wrong Answer:", wrongAnswer
> ? ? print "Total Quiz Time", (b-a)
> ? ? print "Total Number of correct Answer", correctAnswerCounter
> ? ? #asking user to reenter
> ? ? restart= raw_input("Do You want to start the quiz again Yes or 
> No")
> ? ? if(restart=="no"):
> ? ? ? ? print "Thanks for quiz"
> ? ? ? ? break;
> ? ? elif(restart=="yes"):
> ? ? ? ? wrongAnswer=0
> ? ? ? ? correctAnswerCounter=0;
> ? ? ? ? correctAnswer=[];
> ? ? ? ? i=0
> ? ? ? ? while (i<(counter/2)):
> ? ? ? ? ? ? i=i+1
> ? ? ? ? ? ? 
> correctAnswer.append(0)_______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From dyoo at hashcollision.org  Wed Jan  8 22:54:04 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Wed, 8 Jan 2014 13:54:04 -0800
Subject: [Tutor] need help how to run it on python 3.3
In-Reply-To: <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com>
References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com>
 <CAGZAPF6nJ1ZC7b8Y2Brfo9mvUvc8b9qZ5Eee3xGoL+RBx+9PSg@mail.gmail.com>
 <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com>
Message-ID: <CAGZAPF5xbwGtCsMETL9BMdNgiey4juPh_XirZoqdTxSaCvMowA@mail.gmail.com>

Hi S Tareq,

If you can, next time please just copy and paste the error message as
plain text.  Please avoid screenshots unless they really are relevant
to the problem at hand.

There are good reasons why you should prefer plain text when asking
questions on a mailing list like this one.  (1) Screenshots are often
useful but resource-intensive.  (2) Screenshots are difficult to
search and index: folks who are using non-graphical email clients have
no way of helping you, and search engines become less useful when run
across our archives in the presence of non-textual content.


Anyway, the error message you're running into:

    NameError: name 'raw_input' is not defined


is because Python 2's 'raw_input()' has been renamed to Python 3's 'input()'.


Again, please _closely_ read the document:

    http://docs.python.org/3.0/whatsnew/3.0.html#builtins

which lists this and other backwards-incompatible changes to the language.

From denis.spir at gmail.com  Wed Jan  8 23:15:58 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 08 Jan 2014 23:15:58 +0100
Subject: [Tutor] recursion depth
In-Reply-To: <CAO5ffbbM2NdEFYP5OSB3syz2sa67RvhZ1LX9SgPT24GgY7faPw@mail.gmail.com>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
 <lakd83$nrb$1@ger.gmane.org>
 <CAO5ffbbM2NdEFYP5OSB3syz2sa67RvhZ1LX9SgPT24GgY7faPw@mail.gmail.com>
Message-ID: <52CDCE1E.509@gmail.com>

On 01/08/2014 10:11 PM, Keith Winston wrote:
> On Wed, Jan 8, 2014 at 3:42 PM, Emile van Sebille <emile at fenx.com> wrote:
>
>>
>> Without seeing your code it's hard to be specific, but it's obvious you'll
>> need to rethink your approach.  :)
>
>
>
> Yes, it's clear I need to do the bulk of it without recusion, I haven't
> really thought about how to do that. I may or may not ever get around to
> doing it, since this was primarily an exercise in recursion, for me...
> Thanks for your thoughts.

Funny and useful exercise in recursion: write a func that builds str and repr 
expressions of any object, whatever its attributes, inductively. Eg with

	obj.__repr__() = Type(attr1, attr2...)		# as in code
	obj.__str__()  = {id1:attr1 id2:attr2...}	# nicer

Denis

PS: Don't knwo why it's not builtin, would be very useful for debugging, 
testing, any kind of programmer feedback. Guess it has to do with cycles, but 
there are ways to do that; and python manages cycles in list expressions:

spir at ospir:~$ python3
Python 3.3.1 (default, Sep 25 2013, 19:29:01)
[GCC 4.7.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> l1 = [1]
>>> l2 = [1, l1]
>>> l1.extend([l2,l1])
>>> l1
[1, [1, [...]], [...]]
>>> l2
[1, [1, [...], [...]]]

From stareq13 at yahoo.com  Wed Jan  8 21:54:09 2014
From: stareq13 at yahoo.com (S Tareq)
Date: Wed, 8 Jan 2014 20:54:09 +0000 (GMT)
Subject: [Tutor] need help how to run it on python 3.3
In-Reply-To: <CAGZAPF6nJ1ZC7b8Y2Brfo9mvUvc8b9qZ5Eee3xGoL+RBx+9PSg@mail.gmail.com>
References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com>
 <CAGZAPF6nJ1ZC7b8Y2Brfo9mvUvc8b9qZ5Eee3xGoL+RBx+9PSg@mail.gmail.com>
Message-ID: <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com>






On Wednesday, 8 January 2014, 20:46, Danny Yoo <dyoo at hashcollision.org> wrote:
 
Hi S Tareq,


You probably want to review the "What's new in Python 3" document,
with close attention to the "Common Stumbing Blocks" section:

? ? http://docs.python.org/3.0/whatsnew/3.0.html#common-stumbling-blocks

Have you read this document already?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/3f700cb8/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: untitled.JPG
Type: image/jpeg
Size: 121065 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/3f700cb8/attachment-0001.jpe>

From keithwins at gmail.com  Wed Jan  8 23:29:50 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 8 Jan 2014 17:29:50 -0500
Subject: [Tutor] recursion depth
In-Reply-To: <CACL+1auM8YtgNLHBufvJ+W7PX8eCFHbMrpuR732iFGFAYGT-zw@mail.gmail.com>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
 <CACL+1auM8YtgNLHBufvJ+W7PX8eCFHbMrpuR732iFGFAYGT-zw@mail.gmail.com>
Message-ID: <CAO5ffbZaxwwHkBaDZARrcGftpiU-KN2Zxsok0KbcRHKzMUbcfw@mail.gmail.com>

On Wed, Jan 8, 2014 at 4:23 PM, eryksun <eryksun at gmail.com> wrote:

> You can create a worker thread with a larger stack using the threading
> module. On Windows the upper limit is 256 MiB, so give this a try:
>


quite excellent, mwahaha... another shovel to help me excavate out the
bottom of my hole... I'll play with  this someday, but maybe not today. I
seem to be pushing some dangerous limits. Which does happen to be a hobby
of mine.


-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/5ea8bfbe/attachment.html>

From keithwins at gmail.com  Wed Jan  8 23:33:18 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 8 Jan 2014 17:33:18 -0500
Subject: [Tutor] recursion depth
In-Reply-To: <52CDCE1E.509@gmail.com>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
 <lakd83$nrb$1@ger.gmane.org>
 <CAO5ffbbM2NdEFYP5OSB3syz2sa67RvhZ1LX9SgPT24GgY7faPw@mail.gmail.com>
 <52CDCE1E.509@gmail.com>
Message-ID: <CAO5ffbaoLni3Ym9NRz1wkJoo12DqLtETAgK2eDfKzQmtfPr_bg@mail.gmail.com>

On Wed, Jan 8, 2014 at 5:15 PM, spir <denis.spir at gmail.com> wrote:

> Funny and useful exercise in recursion: write a func that builds str and
> repr expressions of any object, whatever its attributes, inductively. Eg
> with
>

Hmm, can't say I get the joke. I haven't really played with repr, though I
think I understand it's use. Could you give an example, I'm not sure I
understand the goal?


-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/4fe6bbba/attachment.html>

From breamoreboy at yahoo.co.uk  Wed Jan  8 23:57:06 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 08 Jan 2014 22:57:06 +0000
Subject: [Tutor] need help how to run it on python 3.3
In-Reply-To: <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com>
References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com>
 <CAGZAPF6nJ1ZC7b8Y2Brfo9mvUvc8b9qZ5Eee3xGoL+RBx+9PSg@mail.gmail.com>
 <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com>
Message-ID: <lakl41$kt8$1@ger.gmane.org>

On 08/01/2014 20:54, S Tareq wrote:
>
> On Wednesday, 8 January 2014, 20:46, Danny Yoo <dyoo at hashcollision.org>
> wrote:
> Hi S Tareq,
>
> You probably want to review the "What's new in Python 3" document,
> with close attention to the "Common Stumbing Blocks" section:
>
> http://docs.python.org/3.0/whatsnew/3.0.html#common-stumbling-blocks
>
> Have you read this document already?
>

Please don't attach 118kb screenshot files when you could have used cut 
and paste for the four lines that are relevant.

-- 
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  Thu Jan  9 00:16:03 2014
From: davea at davea.name (Dave Angel)
Date: Wed, 08 Jan 2014 18:16:03 -0500
Subject: [Tutor] recursion depth
In-Reply-To: <CACL+1auM8YtgNLHBufvJ+W7PX8eCFHbMrpuR732iFGFAYGT-zw@mail.gmail.com>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
 <CACL+1auM8YtgNLHBufvJ+W7PX8eCFHbMrpuR732iFGFAYGT-zw@mail.gmail.com>
Message-ID: <almarsoft.2895114478607169967@news.gmane.org>

On Wed, 8 Jan 2014 16:23:06 -0500, eryksun <eryksun at gmail.com> wrote:
> On Wed, Jan 8, 2014 at 3:25 PM, Keith Winston <keithwins at gmail.com> 
wrote:
> > I've been playing with recursion, it's very satisfying.
> >
> > However, it appears that even if I sys.setrecursionlimit(100000), 
it blows
> > up at about 24,000 (appears to reset IDLE). I guess there must be 
a lot of
> > overhead with recursion, if only 24k times are killing my memory?

I can't see the bodies of any of your messages (are you perchance 
posting in html? ),  but I think there's a good chance you're abusing 
recursion and therefore hitting the limit much sooner than necessary. 
 I've seen some code samples here using recursion to fake a goto,  
for example.  One question to ask is whether each time you recurse, 
are you now solving a simpler problem. 

For example,  when iterating over a tree you should only recurse when 
processing a SHALLOWER subtree.

-- 
DaveA


From davea at davea.name  Thu Jan  9 00:22:57 2014
From: davea at davea.name (Dave Angel)
Date: Wed, 08 Jan 2014 18:22:57 -0500
Subject: [Tutor] need help how to run it on python 3.3
In-Reply-To: <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com>
References: <1389205145.47429.YahooMailNeo@web173004.mail.ir2.yahoo.com>
 <CAGZAPF6nJ1ZC7b8Y2Brfo9mvUvc8b9qZ5Eee3xGoL+RBx+9PSg@mail.gmail.com>
 <1389214449.37321.YahooMailNeo@web173002.mail.ir2.yahoo.com>
Message-ID: <almarsoft.7869102357756813729@news.gmane.org>

On Wed, 8 Jan 2014 20:54:09 +0000 (GMT), S Tareq <stareq13 at yahoo.com> 
wrote:
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

This is a text newsgroup.  Html messages and attachments of any kind 
(especially binary ones) are out of place. 

Guessing that you're trying to show an error message,  I'd suggest 
copy/paste not screen shot.  And if your terminal type doesn't seem 
to support the clipboard,  tell us what you're using and somebody 
will probably have a suggestion.

-- 
DaveA


From keithwins at gmail.com  Thu Jan  9 00:58:52 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 8 Jan 2014 18:58:52 -0500
Subject: [Tutor] recursion depth
In-Reply-To: <almarsoft.2895114478607169967@news.gmane.org>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
 <CACL+1auM8YtgNLHBufvJ+W7PX8eCFHbMrpuR732iFGFAYGT-zw@mail.gmail.com>
 <almarsoft.2895114478607169967@news.gmane.org>
Message-ID: <CAO5ffbZGES=SU3wAVOauMskmGynJBtS9kF9pNr7Bw2s3a0t7LQ@mail.gmail.com>

On Wed, Jan 8, 2014 at 6:16 PM, Dave Angel <davea at davea.name> wrote:

> I can't see the bodies of any of your messages (are you perchance posting
> in html? ),  but I think there's a good chance you're abusing recursion and
> therefore hitting the limit much sooner than necessary. I've seen some code
> samples here using recursion to fake a goto,  for example.  One question to
> ask is whether each time you recurse, are you now solving a simpler
> problem.
> For example,  when iterating over a tree you should only recurse when
> processing a SHALLOWER subtree.
>

Hi Dave: I've been taken to task so often here about having unnecessary
chaff in my email replies, that I started getting in the habit of deleting
everything (since gmail by (unadjustable) default quotes the entire message
string unless you highlight/reply). Since I look at messages in a threaded
manner, I wasn't really realizing how much of a pain that was for others.
I'm trying to  re-establish a highlight/reply habit, like this.

I don't THINK I'm misusing recursion, I think I'm just recursing ridiculous
things. The problem came in creating palindrome numbers. Apparently, if you
add a number to it's reversal (532 + 235), it will be a palindrome, or do
it again (with the first result)... with the only mysterious exception of
196, as I understand it. Interestingly, most numbers reach this palindrome
state rather quickly: in the first 1000 numbers, here are the number of
iterations it takes (numbers don't get credit for being palindromes before
you start):

{0: 13, 1: 291, 2: 339, 3: 158, 4: 84, 5: 33, 6: 15, 7: 18, 8: 10, 10: 2,
11: 8, 14: 2, 15: 8, 16: 1, 17: 5, 19: 1, 22: 2, 23: 8, 24: 2}

Zero stands for where I ran out of recursion depth, set at the time at
9900. Except for the first zero, which is set at 196. It's sort of
fascinating: those two 24's both occur in the first 100.

So it hardly ever takes any iterations to palindromize a number, except
when it takes massive numbers. Except in the single case of 196, where it
never, ever happens apparently (though I understand this to not be proven,
merely tested out to a few million places).

-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140108/47190e49/attachment-0001.html>

From eryksun at gmail.com  Thu Jan  9 06:27:11 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 9 Jan 2014 00:27:11 -0500
Subject: [Tutor] garbage collecting
In-Reply-To: <CAHVvXxTg4RVMQ9EPQmqb_eJ+Eb49Vvbw=O=AgJx=++C_nnb6aA@mail.gmail.com>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org>
 <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>
 <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando>
 <CAO5ffbZBZgCO7s9+s0Mh_q6wOPFES2t995kGZe2P+T33rkVb_g@mail.gmail.com>
 <CAHVvXxTg4RVMQ9EPQmqb_eJ+Eb49Vvbw=O=AgJx=++C_nnb6aA@mail.gmail.com>
Message-ID: <CACL+1atG1LqZ7p-kMVguH0--24tWYuMYtWvcPEgLaeCYMQ3H6g@mail.gmail.com>

On Wed, Jan 8, 2014 at 3:30 PM, Oscar Benjamin
<oscar.j.benjamin at gmail.com> wrote:
> The garbage collector has nothing to do with the memory usage of immutable
> types like ints. There are deallocated instantly when the last reference you
> hold is cleared (in CPython). So if you run out of memory because of them
> then it is because you're keeping them alive in your own code. Running the
> garbage collector with gc.collect cannot help with that.

Object deallocation in CPython doesn't necessarily free memory to the
system. A deallocated object can go on a freelist, or it could have
been allocated out of an obmalloc arena that persists. Either way this
can lead to to a heap high-water mark. 3.3 avoids this wrt obmalloc by
using POSIX mmap instead of malloc, and 3.4 uses Windows VirtualAlloc
(whereas malloc uses HeapAlloc). It doesn't need malloc to manage
small blocks; that's its job after all.

Calling gc.collect(generation=2) will clear freelists for several
built-in types, which may enable the heap to shrink if there's a
high-water mark lingering in a freelist. This is mostly a concern
prior to 3.3. float was the last holdout. It used the original
freelist design until 3.3. Per issue 14435 it was transitioned to
using obmalloc.

The old float freelist was the same design as the one for 2.x int
(PyInt, not PyLong), which grows without bound. The design also
allocates objects in 1 KiB blocks (approx. size). glibc's malloc will
use the heap for a block that's this small.

From keithwins at gmail.com  Thu Jan  9 07:19:15 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 9 Jan 2014 01:19:15 -0500
Subject: [Tutor] garbage collecting
In-Reply-To: <CACL+1atG1LqZ7p-kMVguH0--24tWYuMYtWvcPEgLaeCYMQ3H6g@mail.gmail.com>
References: <CAO5ffbaCdSpt1tzyn7CQxNZD09=mnHdN+TP5_H2hGi3k7MX7fg@mail.gmail.com>
 <laj1fc$i5h$1@ger.gmane.org>
 <CAO5ffbZ9XhY20ToiPWxJqBm0EDQ78WP_LQEhWHvP3962DDEapw@mail.gmail.com>
 <52CD39CA.5030600@gmail.com> <20140108123651.GR29356@ando>
 <CAO5ffbZBZgCO7s9+s0Mh_q6wOPFES2t995kGZe2P+T33rkVb_g@mail.gmail.com>
 <CAHVvXxTg4RVMQ9EPQmqb_eJ+Eb49Vvbw=O=AgJx=++C_nnb6aA@mail.gmail.com>
 <CACL+1atG1LqZ7p-kMVguH0--24tWYuMYtWvcPEgLaeCYMQ3H6g@mail.gmail.com>
Message-ID: <CAO5ffbbsM2ecLQ0HNw=753u-R9geM4NN3vY-J0OfEJMHfd3qRg@mail.gmail.com>

On Thu, Jan 9, 2014 at 12:27 AM, eryksun <eryksun at gmail.com> wrote:

> The old float freelist was the same design as the one for 2.x int
> (PyInt, not PyLong), which grows without bound. The design also
> allocates objects in 1 KiB blocks (approx. size). glibc's malloc will
> use the heap for a block that's this small.
>

Thanks Eryksun, pretty sure that's more than I could have known to ask
about garbage collection. But who knows where it will come in handy?


-- 
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140109/6890fe12/attachment.html>

From garry.bettle at gmail.com  Thu Jan  9 09:50:24 2014
From: garry.bettle at gmail.com (Garry Bettle)
Date: Thu, 9 Jan 2014 09:50:24 +0100
Subject: [Tutor] XML parsing when elements contain foreign characters
Message-ID: <CAPUo4G49KOOFi3m_tQ3xwN-dufKodhNhW0dC_k=tMWXgjiVFXg@mail.gmail.com>

Howdy all,

Have you hear the news? Happy New Year!

Hope someone can help. I know this is a tutor list so please feel free to
send me somewhere else.

I'm trying to parse some XML and I'm struggling to reference elements that
contain foreign characters.

Code so far:

# -*- coding: utf-8 -*-

from xml.dom import minidom

xmldoc = minidom.parse('Export.xml')
products = xmldoc.getElementsByTagName('product')
print '%s Products' % len(products)

row_cnt = 0
titles = {}
stocklevel = {}
for product in products:
  row_cnt+=1
  title=product.getElementsByTagName('Titel')[0].firstChild.nodeValue
  stock=product.getElementsByTagName('AntalP?Lager')[0].firstChild.nodeValue
  if title not in titles:
    titles[title]=1
  else:
    titles[title]+=1
  if stock not in stocklevel:
    stocklevel[stock]=1
  else:
    stocklevel[stock]+=1

Traceback (most recent call last):
  File "C:\Python27\Testing Zizzi.py", line 16, in <module>

stock=product.getElementsByTagName('AntalP??Lager')[0].firstChild.nodeValue
IndexError: list index out of range

I've tried to encode the string before giving it to getElementsByTagName
but no joy.

Any ideas?

Many thanks!

Cheers,

Garry
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140109/30686f67/attachment.html>

From rafael.knuth at gmail.com  Thu Jan  9 10:13:46 2014
From: rafael.knuth at gmail.com (Rafael Knuth)
Date: Thu, 9 Jan 2014 10:13:46 +0100
Subject: [Tutor] Python & Django
Message-ID: <CAM-E2X6YCAp6y77d7F8ipiAUFG+Li+-G35kuOed_MtTjWpL94Q@mail.gmail.com>

Hej there,

I am very interested to hear your opinion on which version of Python
to use in conjunction with Django. Currently, I am taking a class at
Udemy and they recommend using Python 2.7 with Django 1.6. because
both versions work well with each other.

Over the last few months I got pretty much used to Python 3.3.0 which
some of you guys recommended to me on this mailing list. Hence, I
would prefer to keep using Python 3x but I am not sure if that's a
good idea. I heard of a couple folks using Python 3.3.0 with Django
1.6 that they ran into issues, and most of them switched back to
Python 2.7.

Your thoughts?
Thanks in advance!

All the best,

Raf

From amrita.g13 at gmail.com  Thu Jan  9 07:51:21 2014
From: amrita.g13 at gmail.com (Amrita Kumari)
Date: Thu, 9 Jan 2014 14:51:21 +0800
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <20140107113002.GJ29356@ando>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
 <20140105224418.GH29356@ando>
 <CAO313kNLTYWBrgEqjZMe3g9iW3kktVPu83RVDJdCSQapwZpBLA@mail.gmail.com>
 <20140107113002.GJ29356@ando>
Message-ID: <CAO313kNdrktBi+chcdpLbXbjye4vYWTTqgj9wJi_3o0VLG0JjQ@mail.gmail.com>

Hi,

Sorry for delay in reply(as internet was very slow from past two
days), I tried this code which you suggested (by saving it in a file):

import csv
with open('19162.csv') as f:
   reader = csv.reader(f)
   for row in reader:
      print(row)
      row[0] = int(row[0])
      key,value = item.split('=', 1)
      value = float(value)
      print(value)

and I got the output as:

C:\Python33>python 8.py
['2', 'ALA', 'C=178.255', 'CA=53.263', 'CB=18.411', '', '', '', '', '', '', '',
'', '', '']
Traceback (most recent call last):
  File "8.py", line 7, in <module>
    key,value = item.split('=', 1)
NameError: name 'item' is not defined

my datafile is like this:

2,ALA,C=178.255,CA=53.263,CB=18.411,,,,,,,,,,
3,LYS,H=8.607,C=176.752,CA=57.816,CB=31.751,N=119.081,,,,,,,,
4,ASN,H=8.185,C=176.029,CA=54.712,CB=38.244,N=118.255,,,,,,,,
5,VAL,H=7.857,HG11=0.892,HG12=0.892,HG13=0.892,HG21=0.954,HG22=0.954,HG23=0.954,C=177.259,CA=64.232,CB=31.524,CG1=21.402,CG2=21.677,N=119.998
6,ILE,H=8.062,HG21=0.827,HG22=0.827,HG23=0.827,HD11=0.807,HD12=0.807,HD13=0.807,C=177.009,CA=63.400,CB=37.177,CG2=17.565,CD1=13.294,N=122.474
7,VAL,H=7.993,HG11=0.879,HG12=0.879,HG13=0.879,HG21=0.957,HG22=0.957,HG23=0.957,C=177.009,CA=65.017,CB=31.309,CG1=21.555,CG2=22.369,N=120.915
8,LEU,H=8.061,HD11=0.844,HD12=0.844,HD13=0.844,HD21=0.810,HD22=0.810,HD23=0.810,C=178.655,CA=56.781,CB=41.010,CD1=25.018,CD2=23.824,N=121.098
9,ASN,H=8.102,C=176.695,CA=54.919,CB=38.674,N=118.347,,,,,,,,
10,ALA,H=8.388,HB1=1.389,HB2=1.389,HB3=1.389,C=178.263,CA=54.505,CB=17.942,N=124.124,,,,,
----------------------
------------------------
where 1st element of each row is the residue no. but it is not
continuous (some are missing also for example the 1st row is starting
from resdiue no. 2 not from 1) second element of each row is the name
of amino acid and rest element of each row are the various atom along
with chemical shift information corresponding to that particular amino
acid for example H=8.388 is showing that atom is H and it has chemical
shift value 8.388. But the arrangement of these atoms in each row are
quite random and in few row there are many more atoms and in few there
are less. This value I got from Shiftx2 web server. I just want to
align the similar atom chemical shift value into one column (along
with residue no.) for example for atom C, it could be:

2 C=178.255
3 C=176.752
4  C=176.029
5 C=177.259
-----------
-----------

for atom H, it could be:

2 H=nil
3 H=8.607
4 H=8.185
5 H=7.857
6 H=8.062
----------------
-----------
and so on. So if a row doesn't have that atom (for ex. row 1 doesn't
have H atom) then if it can print nil that I can undestand that it is
missing for that particular residue. This arrangement I need in order
to compare this chemical shift value with other web server generated
program.

Thanks,
Amrita



and got the output as:

On 1/7/14, Steven D'Aprano <steve at pearwood.info> wrote:
> On Mon, Jan 06, 2014 at 04:57:38PM +0800, Amrita Kumari wrote:
>> Hi Steven,
>>
>> I tried this code:
>>
>> import csv
>> with open('file.csv') as f:
>>      reader = csv.reader(f)
>>      for row in reader:
>>          print(row)
>>          row[0] = int(row[0])
>>
>> up to this extent it is ok; it is ok it is giving the output as:
>>
>> ['1' , ' GLY' ,  'HA2=3.7850' ,  'HA3=3.9130' , ' ' , ' ' , ' ' , ' ']
>> [ '2' ,  'SER' ,  'H=8.8500' ,  'HA=4.3370' ,  'N=115.7570' , ' ' , ' ' ,
>> '
>> ']
>
> It looks like you are re-typing the output into your email. It is much
> better if you copy and paste it so that we can see exactly what happens.
>
>
>> but the command :
>>
>> key, value = row[2].split('=', 1)
>>         value = float(value.strip())
>>         print(value)
>>
>> is giving the value of row[2] element as
>>
>> ['1' , ' GLY' ,  'HA2=3.7850' ,  'HA3=3.9130' , ' ' , ' ' , ' ' , ' ']
>> 3.7850
>> [ '2' ,  'SER' ,  'H=8.8500' ,  'HA=4.3370' ,  'N=115.7570' , ' ' , ' ' ,
>> '
>> ']
>> 8.8500
>
> So far, the code is doing exactly what you told it to do. Take the third
> column (index 2), and split on the equals sign. Convert the part on the
> right of the equals sign to a float, and print the float.
>
>
>> so this is not what I want I want to print all the chemical shift value
>> of
>> similar atom from each row at one time
>
> Okay, then do so. You'll have to write some code to do this.
>
>
>> like this:
>>
>> 1 HA2=3.7850
>> 2 HA2=nil
>> 3 HA2=nil
>
> Where do these values come from?
>
>
>
>> .....
>> ............
>> ..........
>> 13 HA2=nil
>>
>> similarly, for atom HA3:
>>
>> 1 HA3=3.9130
>> 2 HA3=nil
>> 3 HA3=nil
>> ...........
>> ............
>> ............
>> 13 HA3=nil  and so on.
>>
>> so how to split each item into a key and a numeric value
>
> I've already shown you how to split an item into a key and numeric
> value. Here it is again:
>
> key, value = item.split('=', 1)
> value = float(value)
>
>
>> and then search
>> for similar atom and print its chemical shift value at one time along
>> with
>> residue no..
>
> I don't know what a chemical shift value and residue number are.
> Remember, we are Python programmers, not chemists or biochemists or
> whatever your field is. We don't know how to solve your problem, but if
> you describe in simple English terms how you would solve that problem,
> we can probably help you turn it into Python code.
>
> Start with one row, containing this data:
>
> '2', 'SER', 'H=8.8500', 'HA=4.3370', 'N=115.7570', '', '', ''
>
> There are eight columns. What do those columns represent? In simple
> English terms, what would you like to do with those columns? Tell us
> step by step, as if you were explaining to a small child or a computer.
>
>
>
> --
> Steven
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From manojrout70 at gmail.com  Thu Jan  9 01:33:37 2014
From: manojrout70 at gmail.com (Manoj Rout)
Date: Thu, 9 Jan 2014 06:03:37 +0530
Subject: [Tutor] Python function argument passing problem
Message-ID: <CAOJhXnmU6wP+5=v6ZzK+5_OV=LBjHg_a0SjwG2mOLiLcjbQN3Q@mail.gmail.com>

Hi,






I have been working with python from last couple of weeks. As I am new to
python I have a problem with my work. So can you please look into the below
code.





import re

with open('C:\\Users\\Manoj\\Desktop\\XMC1100_rm_v1.0.6_SVD.xml','r') as
xmlfile:

                svdlines = xmlfile.readlines()

                def func_register(num):

                                for num,svdline in enumerate(svdlines):

                                                if '<register>' in svdline:

                                                                start =
num+1

                                                                break

                                for num,svdline in
enumerate(svdlines[start:]):

                                                if '</register>' in svdline:

                                                                end = num+1

                                                                end =
start+end

                                                                break

                                count=0

                                for num,svdline in
enumerate(svdlines[start:end]):

                                                if '<name>' in svdline:

                                                                count +=1

                                                                if count ==
1:


Registername = re.findall('name>([^ ]*)<',svdline)


print "Register Name is:",Registername

                                                if '<addressOffset>' in
svdline:


OffsetAddress_SVD = re.findall('addressOffset>([^ ]*)<',svdline)

                                                                print
"OffsetAddress is :",OffsetAddress_SVD

                                                if '<resetValue>' in
svdline:


resetvalue_SVD = re.findall('resetValue>([^ ]*)<',svdline)

                                                                print
"resetValue in SVD is :",resetvalue_SVD

                                                                end=end+1

                                                                print end







   Here I want to define a recursive function func_register  which will
take the whole contents  of file and file pointer position  in  first
iteration  and do the assigned work. After first iteration  it will update
the file pointer position . Then in second iteration it should start from
that particular position of that file .



                                I have written the above code and this code
will work if it is not inside the function. i. e outside the ?def
func_register()?. So could you please help me iin this and also I have
added the file .







Thanks and regards,

Manoj Kumar Rout
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140109/351a4c9f/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: XMC1100_rm_v1.0.6_SVD.xml
Type: text/xml
Size: 781731 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/tutor/attachments/20140109/351a4c9f/attachment-0001.xml>

From studeni2010 at hotmail.com  Thu Jan  9 09:52:04 2014
From: studeni2010 at hotmail.com (Tihomir Zjajic)
Date: Thu, 9 Jan 2014 09:52:04 +0100
Subject: [Tutor] help
Message-ID: <DUB114-DS3D7A5A0D5A688A5F19146B8B00@phx.gbl>

Please, can you help me convert this code from python 3 to python 2.6
g = input("Enter a vrs_drv:")
vrs_drv = int(g)

def vrs_drv():
    vrs_drv = input("Enter a vrs_drv:")
    if vrs_drv == "21":
        return("1")
    if vrs_drv == "22":
        return("2")
    if vrs_drv == "41":
        return("4")
number1 = vrs_drv()
print("kl_number1:",number1)

def prs_prec():
    prs_prec = input("Enter a prs_prec:")
    if prs_prec == "20":
        return("20")
    if prs_prec == "40":
        return("40")
    if prs_prec == "80":
        return("80")
number2 = prs_prec()
print("kl_number2:",number2)

def teh_kl():
    teh_kl = input("Enter a teh_kl:")
    if teh_kl == "1":
        return("1")
    if teh_kl == "2":
        return("2")
    if teh_kl == "3":
        return("3")
    if teh_kl == "4":
        return("4")
number3 = teh_kl()
print("kl_number3:",number3)

print(number1+number2+number3)
print("\n\nPress the enter key to exit.")

Python 3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit (Intel)]
on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART
>>> ================================
>>>
Enter a vrs_drv:21
Enter a vrs_drv:21
kl_number1: 1
Enter a prs_prec:40
kl_number2: 40
Enter a teh_kl:1
kl_number3: 1
1401


Press the enter key to exit.
>>>



Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)]
on win32







Type "copyright", "credits" or "license()" for more information.

    ****************************************************************
    Personal firewall software may warn about the connection IDLE
    makes to its subprocess using this computer's internal loopback
    interface.  This connection is not visible on any external
    interface and no data is sent to or received from the Internet.
    ****************************************************************

IDLE 2.6.5
>>> ================================ RESTART
>>> ================================
>>>
Enter a vrs_drv:21
Enter a vrs_drv:21
('kl_number1:', None)
Enter a prs_prec:40
('kl_number2:', None)
Enter a teh_kl:2
('kl_number3:', None)

Traceback (most recent call last):
  File "C:/Users/Tihomir/Desktop/arcpadscript/send.py", line 39, in <module>
    print(number1+number2+number3)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'
>>> 

From steve at pearwood.info  Thu Jan  9 11:41:41 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 9 Jan 2014 21:41:41 +1100
Subject: [Tutor] recursion depth
In-Reply-To: <almarsoft.2895114478607169967@news.gmane.org>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
 <CACL+1auM8YtgNLHBufvJ+W7PX8eCFHbMrpuR732iFGFAYGT-zw@mail.gmail.com>
 <almarsoft.2895114478607169967@news.gmane.org>
Message-ID: <20140109104141.GA3869@ando>

On Wed, Jan 08, 2014 at 06:16:03PM -0500, Dave Angel wrote:
> On Wed, 8 Jan 2014 16:23:06 -0500, eryksun <eryksun at gmail.com> wrote:
> >On Wed, Jan 8, 2014 at 3:25 PM, Keith Winston <keithwins at gmail.com> 
> wrote:
> >> I've been playing with recursion, it's very satisfying.
> >>
> >> However, it appears that even if I sys.setrecursionlimit(100000), 
> it blows
> >> up at about 24,000 (appears to reset IDLE). I guess there must be 
> a lot of
> >> overhead with recursion, if only 24k times are killing my memory?
> 
> I can't see the bodies of any of your messages (are you perchance 
> posting in html? ), 

I presume that your question is aimed at Keith.

Yes, Keith's emails have a HTML part and a text part. A half-decent mail 
client should be able to read the text part even if the HTML part 
exists. But I believe you're reading this from gmane's Usenet mirror, is 
that correct? Perhaps there's a problem with gmane, or your news client, 
or both.

Since this is officially a mailing list, HTML mail is discouraged but 
not strongly discouraged (that ship has sailed a long time ago, more's 
the pity...) so long as the sender includes a plain text part too. Which 
Keith does.

Keith, if you are able, and would be so kind, you'll help solve this 
issue for Dave if you configure your mail client to turn so-called "rich 
text" or formatted text off, at least for this mailing list.


-- 
Steven

From steve at pearwood.info  Thu Jan  9 12:17:57 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 9 Jan 2014 22:17:57 +1100
Subject: [Tutor] help
In-Reply-To: <DUB114-DS3D7A5A0D5A688A5F19146B8B00@phx.gbl>
References: <DUB114-DS3D7A5A0D5A688A5F19146B8B00@phx.gbl>
Message-ID: <20140109111757.GB3869@ando>

On Thu, Jan 09, 2014 at 09:52:04AM +0100, Tihomir Zjajic wrote:
> Please, can you help me convert this code from python 3 to python 2.6

Change input() to raw_input(). That will make it compatible with Python 
2.6. But that is not the cause of the error you get. The error that you 
get is that your functions don't always return a value.

For example, if you call prs_prec(), and enter 20, 40 or 80, it will 
return strings "20", "40" or "80". But if you enter 21, it returns 
nothing, or as Python does it, the special value None. Then, later in 
your program, you try to add None, and that doesn't work.

So look at your functions, and think about what they return.


-- 
Steven

From alan.gauld at btinternet.com  Thu Jan  9 12:18:28 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 09 Jan 2014 11:18:28 +0000
Subject: [Tutor] Python function argument passing problem
In-Reply-To: <CAOJhXnmU6wP+5=v6ZzK+5_OV=LBjHg_a0SjwG2mOLiLcjbQN3Q@mail.gmail.com>
References: <CAOJhXnmU6wP+5=v6ZzK+5_OV=LBjHg_a0SjwG2mOLiLcjbQN3Q@mail.gmail.com>
Message-ID: <lam0ho$pfa$1@ger.gmane.org>

On 09/01/14 00:33, Manoj Rout wrote:

> I have been working with python from last couple of weeks. As I am new
> to python I have a problem with my work. So can you please look into the
> below code.
>
> with open('C:\\Users\\Manoj\\Desktop\\XMC1100_rm_v1.0.6_SVD.xml','r') as
> xmlfile:
>
>                  svdlines = xmlfile.readlines()


Your indentation is way too big.
Reduce it to 2-4 spaces and it will be much more readable.
It may be an issue with your mail client but the current
spacing is hard to parse.
I've tried to bring it together but may have misaligned
some blocks in the process...


>
>        def func_register(num):
>

Its usual to define functions outside of the program flow.
ie not inside the with statement. The definition of your
function does not depend on the context of the 'with'
so it can be placed outside.


>                 for num,svdline in enumerate(svdlines):

You just hid the num parameter in your function definition.
Either change the name or lose the parameter.
Also since svdlines is the only global you reference you
should probably just pass it in as a parameter, it will
make your code more reusable.

>                     if '<register>' in svdline:
>                         start = num+1
                           break

>                 for num,svdline in enumerate(svdlines[start:]):

If you never find 'register' above then start will not be set
and you will get an error. Its a good idea to initialize variables.

                       if '</register>' in svdline:
                          end = num+1
                          end = start+end
>                        break
>
>                 count=0
>                 for num,svdline in enumerate(svdlines[start:end]):
                         if '<name>' in svdline:
                             count +=1
                             if count == 1:
                                Registername = re.findall('name>([^ 
]*)<',svdline)
                                print "Register Name is:",Registername
                         if '<addressOffset>' in svdline:
                             OffsetAddress_SVD = 
re.findall('addressOffset>([^ ]*)<',svdline)
                             print "OffsetAddress is :",OffsetAddress_SVD
                         if '<resetValue>' in svdline:
                             resetvalue_SVD = re.findall('resetValue>([^ 
]*)<',svdline)
                             print "resetValue in SVD is :",resetvalue_SVD
                             end=end+1
                             print end


>     Here I want to define a recursive function func_register

It doesn't appear to be recursive? It never calls itself.

> take the whole contents of file and file pointer position

I assume you mean num is the file pointer position?
If so you throw num away almost immediately in your for loop.
And you never return anything from the function.

> iteration  and do the assigned work.

What is the "assigned work"? It doesn't seem to do anything
other than print a few values.

I assume in the following that by iterations you are
referring to the 3 for loops?

> After first iteration  it will update the file pointer position

Its not doing that at the moment. It creates a new variable start.

> Then in second iteration it should start from that particular
 > position of that file .

Yes and it identifies the line after </register>

And the third loop does some testing and printing within
the defined range.

>                                  I have written the above code and this
> code will work if it is not inside the function. i. e outside the ?def
> func_register()?. So could you please help me iin this and also I have
> added the file .

When you say it does not work what exactly happens?
Do you get an error message? If so please post it in its entirety
Do you get the wrong result? What did you expect what did you get?


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Thu Jan  9 12:20:38 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 09 Jan 2014 11:20:38 +0000
Subject: [Tutor] help
In-Reply-To: <DUB114-DS3D7A5A0D5A688A5F19146B8B00@phx.gbl>
References: <DUB114-DS3D7A5A0D5A688A5F19146B8B00@phx.gbl>
Message-ID: <lam0lq$pfa$2@ger.gmane.org>

On 09/01/14 08:52, Tihomir Zjajic wrote:
> Please, can you help me convert this code from python 3 to python 2.6

The main gotchas are that
1) input in Python 3 -> raw_input() in Python 2
2) print (XXX) in Python 3 -> print XXX in Python 2

Start from there then read any error messages and fix as needed.

HTH--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From steve at pearwood.info  Thu Jan  9 12:42:31 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 9 Jan 2014 22:42:31 +1100
Subject: [Tutor] XML parsing when elements contain foreign characters
In-Reply-To: <CAPUo4G49KOOFi3m_tQ3xwN-dufKodhNhW0dC_k=tMWXgjiVFXg@mail.gmail.com>
References: <CAPUo4G49KOOFi3m_tQ3xwN-dufKodhNhW0dC_k=tMWXgjiVFXg@mail.gmail.com>
Message-ID: <20140109114231.GC3869@ando>

On Thu, Jan 09, 2014 at 09:50:24AM +0100, Garry Bettle wrote:

> I'm trying to parse some XML and I'm struggling to reference elements that
> contain foreign characters.

I see from your use of print that you're using Python 2. That means that 
strings '' are actually byte-strings, not text-strings. That makes it 
really easy for mojibake to creep into your program.

Even though you define a coding line for your file (UTF-8, well done!) 
that only effects how Python reads the source code, not how it runs the 
code. So when you have this line:

stock=product.getElementsByTagName('AntalP?Lager')[0].firstChild.nodeValue

the tag name 'AntalP?Lager' is a *byte* string, not the text that you 
include in your file. Let's see what Python does with it in version 2.7. 
This is what I get on my default system:

py> s = 'AntalP?Lager'
py> print repr(s)
'AntalP\xc3\xa5Lager'

You might get something different.

What are those two weird escaped bytes doing in there, instead of ? ? 
They come about because the string s is treated as bytes rather than 
characters. Python 2 tries really hard to hide this fact from you -- for 
instance, it shows some bytes as ASCII characters A, n, t, a, etc. But 
you can't escape from the fact that they're actually bytes, eventually 
it will cause a problem, and here it is:

> Traceback (most recent call last):
>   File "C:\Python27\Testing Zizzi.py", line 16, in <module>
>
> stock=product.getElementsByTagName('AntalP??Lager')[0].firstChild.nodeValue
> IndexError: list index out of range

See the tag name printed in the error message? 'AntalP??Lager'. That is 
a classic example of mojibake, caused by takes bytes interpreted in one 
encoding (say, UTF-8) and incorrectly interpreting them under another 
encoding (say, Latin-1).

There is one right way, and one half-right way, to handle text in Python 
2. They are:

- The right way is to always use Unicode text instead of bytes. Instead 
  of 'AntalP?Lager', use the u prefix to get a Unicode string:

  u'AntalP?Lager'


- The half-right way is to only use ASCII, and then you can get away 
  with '' strings without the u prefix. Americans and English almost 
  always can get away with this, so they often think that Unicode is a 
  waste of time.


My advise is to change all the strings in your program from '' strings 
to u'' strings, and see if the problem is fixed. But it may not be -- 
I'm not an expert on XML processing, and it may turn out that minidom 
complains about the use of Unicode strings. Try it and see.

I expect (but don't know for sure) that what is happening is that you 
have an XML file with a tag AntalP?Lager, but due to the mojibake 
problem, Python is looking for a non-existent tag AntalP??Lager and 
returning an empty list. When you try to index into that list, it's 
empty and so you get the exception.


-- 
Steven

From onyxtic at gmail.com  Thu Jan  9 13:15:22 2014
From: onyxtic at gmail.com (Evans Anyokwu)
Date: Thu, 9 Jan 2014 12:15:22 +0000
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <CAO313kNdrktBi+chcdpLbXbjye4vYWTTqgj9wJi_3o0VLG0JjQ@mail.gmail.com>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
 <20140105224418.GH29356@ando>
 <CAO313kNLTYWBrgEqjZMe3g9iW3kktVPu83RVDJdCSQapwZpBLA@mail.gmail.com>
 <20140107113002.GJ29356@ando>
 <CAO313kNdrktBi+chcdpLbXbjye4vYWTTqgj9wJi_3o0VLG0JjQ@mail.gmail.com>
Message-ID: <CAAXVmZOdag8iSRjdZ7HVWxwONEqFFEJ9npSTp6Tar0jW6CRF-Q@mail.gmail.com>

First,  the error message means 'item' is missing. You will need to assign
your row as the item.

And if you want nil where there is no value, then use if statement to check
there is something otherwise make that empty value 'nil'.

Sorry, gotta run my train just arrived.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140109/b1a93aae/attachment.html>

From davea at davea.name  Thu Jan  9 13:23:13 2014
From: davea at davea.name (Dave Angel)
Date: Thu, 09 Jan 2014 07:23:13 -0500
Subject: [Tutor] Fwd: arrangement of datafile
In-Reply-To: <CAO313kNdrktBi+chcdpLbXbjye4vYWTTqgj9wJi_3o0VLG0JjQ@mail.gmail.com>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <almarsoft.268003525605550397@news.gmane.org>
 <CAO313kNRwwW9BWjqyLatCqpaiThDFM2GyL2ov+uk+gmws_P8=Q@mail.gmail.com>
 <20131227162204.2fcf156a@Hof>
 <CAAXVmZOQBJ=WUHRAYJ+CwinN--vcrp_3U2E9jjO3G_qZ-tRimQ@mail.gmail.com>
 <CAO313kO_YaY-TYEbaMZPqTefexiCyjn1ERPC=ORzNrYLF_sQ0w@mail.gmail.com>
 <CAO313kMLLXRTbfiL1kvHArMeMNn7z-CjTGa1rtr3wiYk7igSxA@mail.gmail.com>
 <20140105224418.GH29356@ando>
 <CAO313kNLTYWBrgEqjZMe3g9iW3kktVPu83RVDJdCSQapwZpBLA@mail.gmail.com>
 <20140107113002.GJ29356@ando>
 <CAO313kNdrktBi+chcdpLbXbjye4vYWTTqgj9wJi_3o0VLG0JjQ@mail.gmail.com>
Message-ID: <almarsoft.5012339063407463131@news.gmane.org>

On Thu, 9 Jan 2014 14:51:21 +0800, Amrita Kumari 
<amrita.g13 at gmail.com> wrote:
> days), I tried this code which you suggested (by saving it in a 
file):




> import csv
> with open('19162.csv') as f:
>    reader = csv.reader(f)
>    for row in reader:
>       print(row)
>       row[0] = int(row[0])
>       key,value = item.split('=', 1)
>       value = float(value)
>       print(value)

> and I got the output as:

> C:\Python33>python 8.py
> ['2', 'ALA', 'C=178.255', 'CA=53.263', 'CB=18.411', '', '', '', '', 
'', '', '',
> '', '', '']

So you can see that row is a list representing one line of the data 
file. Clearly item is intended to be one element of the list, such as 
row[2] or row [3]. Try it first by adding just the line 
    item=row [2]

Then figure how to make a loop over the items in the row.

-- 
DaveA


From __peter__ at web.de  Thu Jan  9 13:41:58 2014
From: __peter__ at web.de (Peter Otten)
Date: Thu, 09 Jan 2014 13:41:58 +0100
Subject: [Tutor] arrangement of datafile
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
Message-ID: <lam5ch$ka3$1@ger.gmane.org>

Amrita Kumari wrote:

> On 17th Dec. I posted one question, how to arrange datafile in a
> particular fashion so that I can have only residue no. and chemical
> shift value of the atom as:
> 1  H=nil
> 2  H=8.8500
> 3  H=8.7530
> 4  H=7.9100
> 5  H=7.4450
> ........
> Peter has replied to this mail but since I haven't subscribe to the
> tutor mailing list earlier hence I didn't receive the reply, I
> apologize for my mistake, today I checked his reply and he asked me to
> do few things:

I'm sorry, I'm currently lacking the patience to tune into your problem 
again, but maybe the script that I wrote (but did not post) back then is of 
help.

The data sample:

$ cat residues.txt
1 GLY HA2=3.7850 HA3=3.9130
2 SER H=8.8500 HA=4.3370 N=115.7570
3 LYS H=8.7530 HA=4.0340 HB2=1.8080 N=123.2380
4 LYS H=7.9100 HA=3.8620 HB2=1.7440 HG2=1.4410 N=117.9810
5 LYS H=7.4450 HA=4.0770 HB2=1.7650 HG2=1.4130 N=115.4790
6 LEU H=7.6870 HA=4.2100 HB2=1.3860 HB3=1.6050 HG=1.5130 HD11=0.7690 
HD12=0.7690 HD13=0.7690 N=117.3260
7 PHE H=7.8190 HA=4.5540 HB2=3.1360 N=117.0800
8 PRO HD2=3.7450
9 GLN H=8.2350 HA=4.0120 HB2=2.1370 N=116.3660
10 ILE H=7.9790 HA=3.6970 HB=1.8800 HG21=0.8470 HG22=0.8470 HG23=0.8470 
HG12=1.6010 HG13=2.1670 N=119.0300
11 ASN H=7.9470 HA=4.3690 HB3=2.5140 N=117.8620
12 PHE H=8.1910 HA=4.1920 HB2=3.1560 N=121.2640
13 LEU H=8.1330 HA=3.8170 HB3=1.7880 HG=1.5810 HD11=0.8620 HD12=0.8620 
HD13=0.8620 N=119.1360

The script:

$ cat residues.py
def process(filename):
    residues = {}
    with open(filename) as infile:
        for line in infile:
            parts = line.split()            # split line at whitespace
            residue = int(parts.pop(0))     # convert first item to integer
            if residue in residues:
                raise ValueError("duplicate residue {}".format(residue))
            parts.pop(0)                    # discard second item

            # split remaining items at "=" and put them in a dict,
            # e. g. {"HA2": 3.7, "HA3": 3.9}
            pairs = (pair.split("=") for pair in parts)
            lookup = {atom: float(value) for atom, value in pairs}

            # put previous lookup dict in residues dict
            # e. g. {1: {"HA2": 3.7, "HA3": 3.9}}
            residues[residue] = lookup

    return residues

def show(residues):
    atoms = set().union(*(r.keys() for r in residues.values()))
    residues = sorted(residues.items())
    for atom in sorted(atoms):
        for residue, lookup in residues:
            print "{} {}={}".format(residue, atom, lookup.get(atom, "nil"))
        print
        print "-----------"
        print

if __name__ == "__main__":
    r = process("residues.txt")
    show(r)

Note that converting the values to float can be omitted if all you want to 
do is print them. Finally the output of the script:

$ python residues.py 
1 H=nil
2 H=8.85
3 H=8.753
4 H=7.91
5 H=7.445
6 H=7.687
7 H=7.819
8 H=nil
9 H=8.235
10 H=7.979
11 H=7.947
12 H=8.191
13 H=8.133

-----------

1 HA=nil
2 HA=4.337
3 HA=4.034
4 HA=3.862
5 HA=4.077
6 HA=4.21
7 HA=4.554
8 HA=nil
9 HA=4.012
10 HA=3.697
11 HA=4.369
12 HA=4.192
13 HA=3.817

-----------

[snip]


From stefan_ml at behnel.de  Thu Jan  9 15:56:30 2014
From: stefan_ml at behnel.de (Stefan Behnel)
Date: Thu, 09 Jan 2014 15:56:30 +0100
Subject: [Tutor] XML parsing when elements contain foreign characters
In-Reply-To: <CAPUo4G49KOOFi3m_tQ3xwN-dufKodhNhW0dC_k=tMWXgjiVFXg@mail.gmail.com>
References: <CAPUo4G49KOOFi3m_tQ3xwN-dufKodhNhW0dC_k=tMWXgjiVFXg@mail.gmail.com>
Message-ID: <lamdaj$pv9$1@ger.gmane.org>

Garry Bettle, 09.01.2014 09:50:
> I'm trying to parse some XML and I'm struggling to reference elements that
> contain foreign characters.

I skipped over Steven's response and he apparently invested quite a bit of
time in writing it up so nicely, so I can happily agree and just add one
little comment that you should generally avoid using MiniDOM for XML
processing. Instead, use the ElementTree library, which lives right next to
it in Python's standard library. It's a lot easier to use, and also
performs much better.

http://docs.python.org/library/xml.etree.elementtree.html

Stefan



From davea at davea.name  Thu Jan  9 16:06:36 2014
From: davea at davea.name (Dave Angel)
Date: Thu, 09 Jan 2014 10:06:36 -0500
Subject: [Tutor] recursion depth
In-Reply-To: <20140109104141.GA3869@ando>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
 <CACL+1auM8YtgNLHBufvJ+W7PX8eCFHbMrpuR732iFGFAYGT-zw@mail.gmail.com>
 <almarsoft.2895114478607169967@news.gmane.org> <20140109104141.GA3869@ando>
Message-ID: <almarsoft.5521659242219962791@news.gmane.org>

On Thu, 9 Jan 2014 21:41:41 +1100, Steven D'Aprano 
<steve at pearwood.info> wrote:
> I presume that your question is aimed at Keith.


> Yes, Keith's emails have a HTML part and a text part. A half-decent 
mail 
> client should be able to read the text part even if the HTML part 
> exists. But I believe you're reading this from gmane's Usenet 
mirror, is 
> that correct? Perhaps there's a problem with gmane, or your news 
client, 
> or both.


> Since this is officially a mailing list, HTML mail is discouraged 
but 
> not strongly discouraged (that ship has sailed a long time ago, 
more's 
> the pity...) so long as the sender includes a plain text part too. 
Which 
> Keith does.

Yes I'm pretty sure it's Groundhog's fault. In tutor list, all I see 
of Keith ' messages is the 3-line footer. And in python.general I see 
nothing for such messages. 

I've used outlook express and Thunderbird and xpn for many years 
here. But a couple of months ago I switched to an android tablet,  
and "Groundhog newsreader" and "Android Usenet" have this problem 
with html here. I am using gmane,  but the other gmane sites don't 
have this problem.  Instead they show uninterpreted html on 
groundhog.  Those sites all happen to be googlegroups,  so that's 
another variable. 

Anybody know of an android solution?

-- 
DaveA


From keithwins at gmail.com  Thu Jan  9 19:02:30 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 9 Jan 2014 13:02:30 -0500
Subject: [Tutor] recursion depth
In-Reply-To: <20140109104141.GA3869@ando>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
 <CACL+1auM8YtgNLHBufvJ+W7PX8eCFHbMrpuR732iFGFAYGT-zw@mail.gmail.com>
 <almarsoft.2895114478607169967@news.gmane.org> <20140109104141.GA3869@ando>
Message-ID: <CAO5ffbahuqrDn2cFnT5+0=V8m8XsWRfnO4PFu9O=AVLayTw-iQ@mail.gmail.com>

On Thu, Jan 9, 2014 at 5:41 AM, Steven D'Aprano <steve at pearwood.info> wrote:
>
> Keith, if you are able, and would be so kind, you'll help solve this
> issue for Dave if you configure your mail client to turn so-called "rich
> text" or formatted text off, at least for this mailing list.

Well, hopefully this is plain text. It all looks the same to me, so if
gmail switches back, it might go unnoticed for a while. Sorry for the
incessant hassle.


-- 
Keith

From emile at fenx.com  Thu Jan  9 19:13:23 2014
From: emile at fenx.com (Emile van Sebille)
Date: Thu, 09 Jan 2014 10:13:23 -0800
Subject: [Tutor] Python & Django
In-Reply-To: <CAM-E2X6YCAp6y77d7F8ipiAUFG+Li+-G35kuOed_MtTjWpL94Q@mail.gmail.com>
References: <CAM-E2X6YCAp6y77d7F8ipiAUFG+Li+-G35kuOed_MtTjWpL94Q@mail.gmail.com>
Message-ID: <lamos3$fb1$1@ger.gmane.org>

On 01/09/2014 01:13 AM, Rafael Knuth wrote:
> Hej there,
>
> I am very interested to hear your opinion on which version of Python
> to use in conjunction with Django. Currently, I am taking a class at
> Udemy and they recommend using Python 2.7 with Django 1.6. because
> both versions work well with each other.
>
> Over the last few months I got pretty much used to Python 3.3.0 which
> some of you guys recommended to me on this mailing list. Hence, I
> would prefer to keep using Python 3x but I am not sure if that's a
> good idea. I heard of a couple folks using Python 3.3.0 with Django
> 1.6 that they ran into issues, and most of them switched back to
> Python 2.7.
>
> Your thoughts?


I'm sure the folks on the django list have the best opinions on this.

That said, the installation guide for django says 'It works with Python 
2.6, 2.7, 3.2 or 3.3' so I'd feel free to follow that unless I 
discovered that the areas giving problems would overlap with my specific 
use case.  If django by itself were at some level incompatible with 3.3 
the authors would have either already fixed it or removed 3.3 from the 
'known to work under' list, so I suspect it's still a third party module 
that the django users are having problems with.

YMMV,

Emile




From davea at davea.name  Thu Jan  9 21:10:00 2014
From: davea at davea.name (Dave Angel)
Date: Thu, 09 Jan 2014 15:10:00 -0500
Subject: [Tutor] recursion depth
In-Reply-To: <CAO5ffbahuqrDn2cFnT5+0=V8m8XsWRfnO4PFu9O=AVLayTw-iQ@mail.gmail.com>
References: <CAO5ffbbcXj=V8Wzjkoi-SofxXHu2597qxRxMzrWaQVh_ocfgnA@mail.gmail.com>
 <CACL+1auM8YtgNLHBufvJ+W7PX8eCFHbMrpuR732iFGFAYGT-zw@mail.gmail.com>
 <almarsoft.2895114478607169967@news.gmane.org> <20140109104141.GA3869@ando>
 <CAO5ffbahuqrDn2cFnT5+0=V8m8XsWRfnO4PFu9O=AVLayTw-iQ@mail.gmail.com>
Message-ID: <almarsoft.5478772595971847492@news.gmane.org>

On Thu, 9 Jan 2014 13:02:30 -0500, Keith Winston 
<keithwins at gmail.com> wrote:
> Well, hopefully this is plain text. It all looks the same to me, so 
if
> gmail switches back, it might go unnoticed for a while. Sorry for 
the
> incessant hassle.

That looks great,  thanks.

-- 
DaveA


From amrita.g13 at gmail.com  Fri Jan 10 04:20:21 2014
From: amrita.g13 at gmail.com (Amrita Kumari)
Date: Fri, 10 Jan 2014 11:20:21 +0800
Subject: [Tutor] arrangement of datafile
In-Reply-To: <lam5ch$ka3$1@ger.gmane.org>
References: <CAO313kNVyv4u0S4yRcGSNHA=vMGjCVKGV9nCSZcCWJ3hoLVDNg@mail.gmail.com>
 <lam5ch$ka3$1@ger.gmane.org>
Message-ID: <CAO313kMKfk2mZBvp0eVhBFQ5j+dXhbtdTsWWS-qKN5qfoR7UKw@mail.gmail.com>

Hi Peter,

Thankyou very much for your kind help. I got the output like the way I
wanted (which you have also shown in your output). I really appreciate your
effort.

Thanks for your time.
Amrita


On Thu, Jan 9, 2014 at 8:41 PM, Peter Otten <__peter__ at web.de> wrote:

> Amrita Kumari wrote:
>
> > On 17th Dec. I posted one question, how to arrange datafile in a
> > particular fashion so that I can have only residue no. and chemical
> > shift value of the atom as:
> > 1  H=nil
> > 2  H=8.8500
> > 3  H=8.7530
> > 4  H=7.9100
> > 5  H=7.4450
> > ........
> > Peter has replied to this mail but since I haven't subscribe to the
> > tutor mailing list earlier hence I didn't receive the reply, I
> > apologize for my mistake, today I checked his reply and he asked me to
> > do few things:
>
> I'm sorry, I'm currently lacking the patience to tune into your problem
> again, but maybe the script that I wrote (but did not post) back then is of
> help.
>
> The data sample:
>
> $ cat residues.txt
> 1 GLY HA2=3.7850 HA3=3.9130
> 2 SER H=8.8500 HA=4.3370 N=115.7570
> 3 LYS H=8.7530 HA=4.0340 HB2=1.8080 N=123.2380
> 4 LYS H=7.9100 HA=3.8620 HB2=1.7440 HG2=1.4410 N=117.9810
> 5 LYS H=7.4450 HA=4.0770 HB2=1.7650 HG2=1.4130 N=115.4790
> 6 LEU H=7.6870 HA=4.2100 HB2=1.3860 HB3=1.6050 HG=1.5130 HD11=0.7690
> HD12=0.7690 HD13=0.7690 N=117.3260
> 7 PHE H=7.8190 HA=4.5540 HB2=3.1360 N=117.0800
> 8 PRO HD2=3.7450
> 9 GLN H=8.2350 HA=4.0120 HB2=2.1370 N=116.3660
> 10 ILE H=7.9790 HA=3.6970 HB=1.8800 HG21=0.8470 HG22=0.8470 HG23=0.8470
> HG12=1.6010 HG13=2.1670 N=119.0300
> 11 ASN H=7.9470 HA=4.3690 HB3=2.5140 N=117.8620
> 12 PHE H=8.1910 HA=4.1920 HB2=3.1560 N=121.2640
> 13 LEU H=8.1330 HA=3.8170 HB3=1.7880 HG=1.5810 HD11=0.8620 HD12=0.8620
> HD13=0.8620 N=119.1360
>
> The script:
>
> $ cat residues.py
> def process(filename):
>     residues = {}
>     with open(filename) as infile:
>         for line in infile:
>             parts = line.split()            # split line at whitespace
>             residue = int(parts.pop(0))     # convert first item to integer
>             if residue in residues:
>                 raise ValueError("duplicate residue {}".format(residue))
>             parts.pop(0)                    # discard second item
>
>             # split remaining items at "=" and put them in a dict,
>             # e. g. {"HA2": 3.7, "HA3": 3.9}
>             pairs = (pair.split("=") for pair in parts)
>             lookup = {atom: float(value) for atom, value in pairs}
>
>             # put previous lookup dict in residues dict
>             # e. g. {1: {"HA2": 3.7, "HA3": 3.9}}
>             residues[residue] = lookup
>
>     return residues
>
> def show(residues):
>     atoms = set().union(*(r.keys() for r in residues.values()))
>     residues = sorted(residues.items())
>     for atom in sorted(atoms):
>         for residue, lookup in residues:
>             print "{} {}={}".format(residue, atom, lookup.get(atom, "nil"))
>         print
>         print "-----------"
>         print
>
> if __name__ == "__main__":
>     r = process("residues.txt")
>     show(r)
>
> Note that converting the values to float can be omitted if all you want to
> do is print them. Finally the output of the script:
>
> $ python residues.py
> 1 H=nil
> 2 H=8.85
> 3 H=8.753
> 4 H=7.91
> 5 H=7.445
> 6 H=7.687
> 7 H=7.819
> 8 H=nil
> 9 H=8.235
> 10 H=7.979
> 11 H=7.947
> 12 H=8.191
> 13 H=8.133
>
> -----------
>
> 1 HA=nil
> 2 HA=4.337
> 3 HA=4.034
> 4 HA=3.862
> 5 HA=4.077
> 6 HA=4.21
> 7 HA=4.554
> 8 HA=nil
> 9 HA=4.012
> 10 HA=3.697
> 11 HA=4.369
> 12 HA=4.192
> 13 HA=3.817
>
> -----------
>
> [snip]
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140110/cfe2f54c/attachment-0001.html>

From amydavidson at sympatico.ca  Fri Jan 10 01:11:49 2014
From: amydavidson at sympatico.ca (Amy Davidson)
Date: Thu, 9 Jan 2014 19:11:49 -0500
Subject: [Tutor] Python Question
Message-ID: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>

Hi,

I am a university student who is struggling with writing functions in Python. I?ve been attempting to write a function in Python for over 2 hours with no progress. The function must be called, printID and take a name and student number as parameter and prints them to the screen.

This is my closest guess:

def print_ID(?Amy Davidson?, 111111111)
Student = ?Amy Davidson?
StudentN = 111111111
print (?StudentName:?, Student)
print (?StudentNumber:?, StudentN)

If you could help correct my work and explain, that would be great! 

Thanks,

Amy Davidson

From carroll at tjc.com  Thu Jan  9 23:30:45 2014
From: carroll at tjc.com (Terry Carroll)
Date: Thu, 9 Jan 2014 14:30:45 -0800 (PST)
Subject: [Tutor] How can a CGI program get the URL that called it?
Message-ID: <alpine.LRH.2.00.1401091420480.5902@aqua.rahul.net>

How can my Python 2.7 CGI program find the URL that caused the program to 
be called?

I have a program that creates a JPG or PNG file on the fly, and needs to 
construct a URL to it. I know the path relative to my program is, for 
example, "../temp/tmpiicack.png" (the filename generated by 
tempfile.NamedTemporaryFile).  From this, I want to generate a URL for the 
image so it can be displayed.

I invoke My CGI program (in testing) with the URL 
http://localhost:8000/cgi-bin/query.py?tmtype=s&tmnumber=76044902. It is 
usually invoked using a form at http://localhost:8000/cgi-bin/query.py, 
which generates the URL, but can also be invoked by directly going to the 
URL with parameters specified (I want to be able to email a complete URL, 
for example).  In this instance, the URL I want to generate would be 
http://localhost:8000/temp/tmpiicack.png.  The problem is, my program does 
not know the "http://localhost:8000" part.

Module urlparse has facilities for generating a URL from relative parts, 
but requires that I know a base URL to begin with. I've looked in 
os.environ to see if anything is presented, but the only thing close is 
os.environ['HTTP_REFERER'], which is only populated if the program is 
invoked from the form-click, not if directly entered (e.g. copy/paste).

(That's my fall-back solution; but it will mean the image-support will 
fail if a URL is entered directly, and will work only if invoked from a 
form.)

I've also checked os.environ['PATH_INFO'] as suggested in a post on 
stackoverflow,[1] but that is not populated.  (I can't recall whether it's 
a zero-length string or None, but it has nothing useful).

I'm testing using CGIHTTPServer as my server, if it matters.


[1] 
http://stackoverflow.com/questions/4939067/catching-the-url-path-following-a-python-cgi-script/4939137#4939137


From breamoreboy at yahoo.co.uk  Fri Jan 10 10:33:09 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Fri, 10 Jan 2014 09:33:09 +0000
Subject: [Tutor] Python Question
In-Reply-To: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
Message-ID: <laoeoi$kcb$1@ger.gmane.org>

On 10/01/2014 00:11, Amy Davidson wrote:
> Hi,
>
> I am a university student who is struggling with writing functions in Python. I?ve been attempting to write a function in Python for over 2 hours with no progress. The function must be called, printID and take a name and student number as parameter and prints them to the screen.
>
> This is my closest guess:
>
> def print_ID(?Amy Davidson?, 111111111)

The def line should finish with a colon.  How do you expect to call this 
function for "Mark Lawrence", 1?  Research something like:- python 
functions parameters arguments.

> Student = ?Amy Davidson?
> StudentN = 111111111
> print (?StudentName:?, Student)
> print (?StudentNumber:?, StudentN)

All four of your lines above should be indented, or have they been lost 
by your email client?  You simply assign to Student and StudentN which 
you then print.  Look closely at this, look back to my earlier comment, 
add them and hopefully the answer is 4 :)  Incidentally you'd usually 
spell them student and studentN.

>
> If you could help correct my work and explain, that would be great!
>
> Thanks,
>
> Amy Davidson


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

Mark Lawrence


From cowtux250 at gmail.com  Fri Jan 10 10:23:51 2014
From: cowtux250 at gmail.com (jargon)
Date: Fri, 10 Jan 2014 11:23:51 +0200
Subject: [Tutor] Python Question
In-Reply-To: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
Message-ID: <52CFBC27.9030707@gmail.com>

On 01/10/2014 02:11 AM, Amy Davidson wrote:
> Hi,
>
> I am a university student who is struggling with writing functions in Python. I?ve been attempting to write a function in Python for over 2 hours with no progress. The function must be called, printID and take a name and student number as parameter and prints them to the screen.
>
> This is my closest guess:
>
> def print_ID(?Amy Davidson?, 111111111)
> Student = ?Amy Davidson?
> StudentN = 111111111
> print (?StudentName:?, Student)
> print (?StudentNumber:?, StudentN)
>
> If you could help correct my work and explain, that would be great! 
>
> Thanks,
>
> Amy Davidson
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
Hi Amy

Your function will need function parameters, to which values will be
passed to:

def printID(studentName, studentNumber):
    print "Student Name: %s. Student Number: %d" %(studentName,
studentNumber)

Then you invoke the function like this:

printID("Amy Davidson", 111111111)

Hope this helps

Dayo

From keithwins at gmail.com  Fri Jan 10 11:13:26 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 10 Jan 2014 05:13:26 -0500
Subject: [Tutor] Python Question
In-Reply-To: <laoeoi$kcb$1@ger.gmane.org>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
 <laoeoi$kcb$1@ger.gmane.org>
Message-ID: <CAO5ffbZZiKEg22mtSNdR5wEp4vxVN7JEy7=YpYZ2K53-oec-ZA@mail.gmail.com>

Amy, you may want to get a little clearer on the difference between
defining a function, and calling one. The definition is sort of a
generic process, it's when you are calling it that you really fill in
the blanks, and the function does what it's designed for (whether you
like it or not!).

You might even try breaking it down a little further, maybe write a
function with just one parameter, and call it a few times to get the
hang of it. In fact, try calling some of the built-in functions (for
example, you can get the length of a string s = "hello" by calling
'len(s)'). You can do all this at the python prompt, but as things get
more complicated it's less frustrating to do it saved to a file (are
you doing all this in IDLE?).

keith

From alan.gauld at btinternet.com  Fri Jan 10 11:19:44 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 10 Jan 2014 10:19:44 +0000
Subject: [Tutor] Python Question
In-Reply-To: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
Message-ID: <laohfk$klv$1@ger.gmane.org>

On 10/01/14 00:11, Amy Davidson wrote:
> Hi,
>
> I am a university student who is struggling with writing functions in Python.

You could try reading the functions and modules topic in
my tutorial.(see below)

> The function must be called, printID and take a name and student number
 > as parameter and prints them to the screen.
>
> This is my closest guess:
>
> def print_ID(?Amy Davidson?, 111111111)

The def printID bit is fine but you were supposeed to have *parameers* 
fore name and student number. A parameter is like a variable, its a 
generic name that you later assign a value to when you call the function.

Thus here is a simple function that adds 5 to the number
passed to it

def add5(n):
    ...

First, note the colon after the function definition, that's important.
Now, n is a parameter, a place marker that we can use inside
our function. When we call add5() we provide a value, called
the argument:

result = add5(3)

Now inside the add5() function n has the value 3.

So for your function you need to provide two parameters called,
maybe, say, 'student' and 'studentN'? (It's traditional to have
parameter names start with lower case letters. Python doesn't
care but it makes it easier for other programmers - or you
later on - to recognise what they are)

> Student = ?Amy Davidson?
> StudentN = 111111111
> print (?StudentName:?, Student)
> print (?StudentNumber:?, StudentN)

The lines that make up a function body must be indented under
the def line. For example in my add5() example it would look
like:

def add5(n):
     return n+5

So your four lines above need to be indented, and once
you create parameters the first two will not be needed.

Once you have that down you can then test your function by calling it 
with whatever values you want printed:

printID("Amy Davidson", 111111111)
printID("Bill Gates", 12345678)
etc...


hth
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Fri Jan 10 11:36:02 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 10 Jan 2014 10:36:02 +0000
Subject: [Tutor] How can a CGI program get the URL that called it?
In-Reply-To: <alpine.LRH.2.00.1401091420480.5902@aqua.rahul.net>
References: <alpine.LRH.2.00.1401091420480.5902@aqua.rahul.net>
Message-ID: <laoie6$vqp$1@ger.gmane.org>

On 09/01/14 22:30, Terry Carroll wrote:
> How can my Python 2.7 CGI program find the URL that caused the program
> to be called?

You don't say what modules or toolkits you are using but I'll assume for 
now its the standard library cgi module?

I'm not sure what you are looking for. Is it the url that the user 
clicked on in their browser? Why would you need that dynamically,
its calling your file. You should know where your file is?
Or is your file being called from many different page links and you want 
the specific link? Usually that's done by adding a marker to the 
submitted data on the form?

If you want to create a png file and display it to the user
then you just store the file somewhere in your web site and
create an html file that has an img tag referencing that location.
You shouldn't need the calling url to do that unless you
are working across multiple web sites or somesuch.

Can you explain a bit more about the use case that requires you
to know the incoming url?


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From keithwins at gmail.com  Fri Jan 10 11:16:21 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 10 Jan 2014 05:16:21 -0500
Subject: [Tutor] Python Question
In-Reply-To: <CAO5ffbZZiKEg22mtSNdR5wEp4vxVN7JEy7=YpYZ2K53-oec-ZA@mail.gmail.com>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
 <laoeoi$kcb$1@ger.gmane.org>
 <CAO5ffbZZiKEg22mtSNdR5wEp4vxVN7JEy7=YpYZ2K53-oec-ZA@mail.gmail.com>
Message-ID: <CAO5ffbZ8qBmtqDyw3=OtPky7HWbHSVx1=Zd+RV_arwUHyQibqQ@mail.gmail.com>

Amy, be aware that there are slightly different versions of Python
floating around, and the example Dayo gave you uses a slightly
different print statement (no parens) than the example you provided
(which probably indicates that your Python requires them).

Good luck, you're on your way!

Keith

From denis.spir at gmail.com  Fri Jan 10 11:43:29 2014
From: denis.spir at gmail.com (spir)
Date: Fri, 10 Jan 2014 11:43:29 +0100
Subject: [Tutor] Python Question
In-Reply-To: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
Message-ID: <52CFCED1.40502@gmail.com>

On 01/10/2014 01:11 AM, Amy Davidson wrote:
> Hi,
>
> I am a university student who is struggling with writing functions in Python. I?ve been attempting to write a function in Python for over 2 hours with no progress. The function must be called, printID and take a name and student number as parameter and prints them to the screen.
>
> This is my closest guess:
>
> def print_ID(?Amy Davidson?, 111111111)
> Student = ?Amy Davidson?
> StudentN = 111111111
> print (?StudentName:?, Student)
> print (?StudentNumber:?, StudentN)
>
> If you could help correct my work and explain, that would be great!
>
> Thanks,
>
> Amy Davidson

You are confusing *defining* a function and *executing* it. Below a trial at 
explaining. You may have a part of program that does this:

	name = "toto"
	ident = 123

	print(name, ident)	# the performing part

Now, say instead of a single line, the "performance" is bigger or more 
complicated and, most importantly, forms a whole conceptually. For instance, it 
may be a piece of code that (1) reads and properly structures input data or (2) 
processes them or (3) outputs results in a format convenient to the user. If you 
structure program application that way, then it looks like

	data = read_input(where)
	results = process(data)
	write_report(results)

which is quite clear, isn't it? Functions (procedures, routines, etc...) are 
used first to provide such a clear structure to a program, which otherwise would 
be a huge mess. Another reason why functions (etc...) are necessary is that one 
often uses pieces of code multiple times, maybe millions of times even when 
applying the same process to a big store of data. Yet another reason is to build 
a toolkit for standard or common tasks, that one can reuse at will when needed 
--and that's what a language comes with: standard / primitive / builtin routines 
for the most common tasks. And then we construct more sophisticated processes 
from these building blocks, according to our app's needs.

Now, back to concrete. To define and use a function, one proceeds as follows 
(example):

# define function:
def average (numbers):
     count = len(numbers)    	# len means length"
     total = sum(numbers)
     return total / count

# use function:
nums = [1,3,9]
x = average(nums)
print(x)    			# ==> 4.333333333333333

You first define the function using a "def" instruction. The function nearly 
always takes some input variable(s) called "paramaters", here 'numbers'. And 
often returns a result [*].

I think and hope you have enough information to do it in your case; and in a 
variety of other cases you may like to try and play with :-)

Denis

[*] Else, rather than a function properly, it is an action that *does* something 
but usually does not return any result. For instance, 'write_report' above is an 
action.



From fomcl at yahoo.com  Fri Jan 10 18:11:23 2014
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Fri, 10 Jan 2014 09:11:23 -0800 (PST)
Subject: [Tutor] arrangement of datafile
In-Reply-To: <lam5ch$ka3$1@ger.gmane.org>
Message-ID: <1389373883.10506.YahooMailBasic@web163803.mail.gq1.yahoo.com>


Ok, it's clear already that the OP has a csv file so the following is OFF-TOPIC. I was reading Python Cookbook and I saw a recipe to read fixed width files using struct.unpack. Much shorter and faster (esp. if you use compiled structs) than indexing. I thought this is a pretty cool approach: http://code.activestate.com/recipes/65224-accessing-substrings/.

regards,
Albert-Jan


From dyoo at hashcollision.org  Fri Jan 10 20:14:23 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 10 Jan 2014 11:14:23 -0800
Subject: [Tutor] Python Question
In-Reply-To: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
Message-ID: <CAGZAPF7vHKMf7-U1HT=mwjDdmOkYCnjk1MB3XiQ5SmPxjKhmQw@mail.gmail.com>

Hi Amy,

Have you seen any other examples of functions in your instruction, either
in your books or notes?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140110/1d3d300a/attachment.html>

From dyoo at hashcollision.org  Fri Jan 10 20:57:51 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 10 Jan 2014 11:57:51 -0800
Subject: [Tutor] Python Question
In-Reply-To: <BLU0-SMTP335F2BC055B4B9C4C58094C8B30@phx.gbl>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
 <CAGZAPF7vHKMf7-U1HT=mwjDdmOkYCnjk1MB3XiQ5SmPxjKhmQw@mail.gmail.com>
 <BLU0-SMTP335F2BC055B4B9C4C58094C8B30@phx.gbl>
Message-ID: <CAGZAPF7JXiw=bXi0hv-xLCE5wgX2EJjoi8Y65kVEcU9sEieSWA@mail.gmail.com>

I repeat my question in the hopes that you read it.  Do you have other
examples of functions you have written or seen?

I ask this because if you have never seen a function definition, our advice
is radically different than if you have.

Just giving us the homework statement is fairly useless to us: how does
that help us figure out what part **you** are having difficult with?
On Jan 10, 2014 11:25 AM, "Amy Davidson" <amydavidson at sympatico.ca> wrote:

> hi Danny,
>
> Below are the instructions.
>
> Write a function called printID that takes a name and student number as
> parameters and prints them to the screen.
> E.g.:
> >>> printID("Andrew Joe", 100555555) #note the second parameter *must* be
> of type int
>   "Student Name: Andrew Joe"
>   "Student Number: 100555555"
> On Jan 10, 2014, at 2:14 PM, Danny Yoo <dyoo at hashcollision.org> wrote:
>
> Hi Amy,
>
> Have you seen any other examples of functions in your instruction, either
> in your books or notes?
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140110/5a02c505/attachment.html>

From keithwins at gmail.com  Fri Jan 10 23:00:04 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 10 Jan 2014 17:00:04 -0500
Subject: [Tutor] Python Question
In-Reply-To: <CAGZAPF7JXiw=bXi0hv-xLCE5wgX2EJjoi8Y65kVEcU9sEieSWA@mail.gmail.com>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
 <CAGZAPF7vHKMf7-U1HT=mwjDdmOkYCnjk1MB3XiQ5SmPxjKhmQw@mail.gmail.com>
 <BLU0-SMTP335F2BC055B4B9C4C58094C8B30@phx.gbl>
 <CAGZAPF7JXiw=bXi0hv-xLCE5wgX2EJjoi8Y65kVEcU9sEieSWA@mail.gmail.com>
Message-ID: <CAO5ffbaM88sfDfJnW=m=ixQK2PhUNm3ZppQo-NpaQGwpjZ9Esg@mail.gmail.com>

Amy, judging from Danny's replies, you may be emailing him and not the
list. If you want others to help, or to report on your progress,
you'll need to make sure the tutor email is in your reply to:

Often, people prefer you to respond to the list, if there isn't
something particularly personal in your response. Good luck with
learning Python, it's great language, and this is a very helpful
group. I do realize that learning your first computer language can be
disorienting.

Keith

On Fri, Jan 10, 2014 at 2:57 PM, Danny Yoo <dyoo at hashcollision.org> wrote:
> I repeat my question in the hopes that you read it.  Do you have other
> examples of functions you have written or seen?
>
> I ask this because if you have never seen a function definition, our advice
> is radically different than if you have.
>
> Just giving us the homework statement is fairly useless to us: how does that
> help us figure out what part **you** are having difficult with?
>
> On Jan 10, 2014 11:25 AM, "Amy Davidson" <amydavidson at sympatico.ca> wrote:
>>
>> hi Danny,
>>
>> Below are the instructions.
>>
>> Write a function called printID that takes a name and student number as
>> parameters and prints them to the screen.
>>
>> E.g.:
>> >>> printID("Andrew Joe", 100555555) #note the second parameter must be of
>> >>> type int
>>   "Student Name: Andrew Joe"
>>   "Student Number: 100555555"
>> On Jan 10, 2014, at 2:14 PM, Danny Yoo <dyoo at hashcollision.org> wrote:
>>
>> Hi Amy,
>>
>> Have you seen any other examples of functions in your instruction, either
>> in your books or notes?
>>
>>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Keith

From dyoo at hashcollision.org  Fri Jan 10 23:10:31 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 10 Jan 2014 14:10:31 -0800
Subject: [Tutor] How can a CGI program get the URL that called it?
In-Reply-To: <alpine.LRH.2.00.1401091420480.5902@aqua.rahul.net>
References: <alpine.LRH.2.00.1401091420480.5902@aqua.rahul.net>
Message-ID: <CAGZAPF5kNPqiEFuW-sq=paEGB+3-khhsN0B7EQ8+nhV8Ms=X8g@mail.gmail.com>

On Thu, Jan 9, 2014 at 2:30 PM, Terry Carroll <carroll at tjc.com> wrote:
> How can my Python 2.7 CGI program find the URL that caused the program to be
> called?

Hi Terry,

According to the description of CGI:

    http://en.wikipedia.org/wiki/Common_Gateway_Interface

there should be a set of environmental variables that your program can
observe to reconstruct that portion of the request string.

In particular, you should be seeing SERVER_NAME, SERVER_PORT, and
other environmental variables if CGIHTTPServer from the Python
standard library is implementing the CGI protocol.

Checking...

    http://hg.python.org/cpython/file/0e5df5b62488/Lib/CGIHTTPServer.py#l157

Yes, you should be seeing SERVER_NAME and SERVER_PORT, unless
something strange is happening.

From dyoo at hashcollision.org  Fri Jan 10 23:25:09 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 10 Jan 2014 14:25:09 -0800
Subject: [Tutor] Python Question
In-Reply-To: <CAO5ffbaM88sfDfJnW=m=ixQK2PhUNm3ZppQo-NpaQGwpjZ9Esg@mail.gmail.com>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
 <CAGZAPF7vHKMf7-U1HT=mwjDdmOkYCnjk1MB3XiQ5SmPxjKhmQw@mail.gmail.com>
 <BLU0-SMTP335F2BC055B4B9C4C58094C8B30@phx.gbl>
 <CAGZAPF7JXiw=bXi0hv-xLCE5wgX2EJjoi8Y65kVEcU9sEieSWA@mail.gmail.com>
 <CAO5ffbaM88sfDfJnW=m=ixQK2PhUNm3ZppQo-NpaQGwpjZ9Esg@mail.gmail.com>
Message-ID: <CAGZAPF41DH3cRjJVjtBzU93i=cKowptVf4eEtGixm+1trF1S0A@mail.gmail.com>

On Fri, Jan 10, 2014 at 2:00 PM, Keith Winston <keithwins at gmail.com> wrote:
> Amy, judging from Danny's replies, you may be emailing him and not the
> list. If you want others to help, or to report on your progress,
> you'll need to make sure the tutor email is in your reply to:

Hi Amy,

Very much so.  Please try to use "Reply to All" if you can.

If you're wondering why I'm asking for you to try to recall any other
example function definitions, I'm doing so specifically because it is
a general problem-solving technique.  Try to see if the problem that's
stumping you is similar to things you've seen before.  Several of the
heuristics from Polya's "How to Solve It" refer to this:

    http://en.wikipedia.org/wiki/How_to_Solve_It

If you haven't ever seen any function definition ever before, then we
do have to start from square one.  But this would be a very strange
scenario, to be asked to write a function definition without having
seen any previous definitions before.

If you have seen a function before, then one approach we might take is
try to make analogies to those previous examples.  That's an approach
I'd prefer.

From carroll at tjc.com  Fri Jan 10 23:44:35 2014
From: carroll at tjc.com (Terry Carroll)
Date: Fri, 10 Jan 2014 14:44:35 -0800 (PST)
Subject: [Tutor] How can a CGI program get the URL that called it?
In-Reply-To: <laoie6$vqp$1@ger.gmane.org>
References: <alpine.LRH.2.00.1401091420480.5902@aqua.rahul.net>
 <laoie6$vqp$1@ger.gmane.org>
Message-ID: <alpine.LRH.2.00.1401101356290.28530@aqua.rahul.net>

Ah, I discovered what my problem was...

On Fri, 10 Jan 2014, Alan Gauld wrote:

> its calling your file. You should know where your file is?

My problem was that, I know where the file is in the host's file system, 
and relative to my CGI program.  I do not have a URL to that file.

> If you want to create a png file and display it to the user then you 
> just store the file somewhere in your web site and create an html file 
> that has an img tag referencing that location.

Right; I am producing HTML output (using the print command, not as a 
file), with an img tag.  The img tag has a src attribute, which must 
provide the URL of the referenced image file.

But I do not have that URL.  I know where that file is in the file system, 
and relative to my CGI program.  But I do not have a URL to the file.  My 
thinking was that, if I have the URL to my program, it's pretty trivial to 
construct the URL to the file.

And here's where my real problem was:  I had tried specifying just a 
relative path in the src tag, and that did not work consistently; 
specifically, I found that it worked in Chrome, but not Firefox.

As it turns out, since I was testing on a Windows box, os.path.relpath was 
(reasonably) using a '\' as the separator character (surprisingly, so does 
posixpath.relpath).  By simply adding:

    relative_path = relative_path.replace('\\', '/')

It uses the '/' required in a URL (even a relative-path URL) and works. 
Chrome was forgiving of the '\'; other browsers not so much.

It was not until I posted the <img> tag into a draft of this reply that I 
noticed the '\' characters.

I swear I looked at this for hours without noticing this before.

From steve at pearwood.info  Sat Jan 11 00:43:11 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 11 Jan 2014 10:43:11 +1100
Subject: [Tutor] How can a CGI program get the URL that called it?
In-Reply-To: <alpine.LRH.2.00.1401101356290.28530@aqua.rahul.net>
References: <alpine.LRH.2.00.1401091420480.5902@aqua.rahul.net>
 <laoie6$vqp$1@ger.gmane.org>
 <alpine.LRH.2.00.1401101356290.28530@aqua.rahul.net>
Message-ID: <20140110234310.GL3869@ando>

On Fri, Jan 10, 2014 at 02:44:35PM -0800, Terry Carroll wrote:

> As it turns out, since I was testing on a Windows box, os.path.relpath was 
> (reasonably) using a '\' as the separator character (surprisingly, so does 
> posixpath.relpath).

Are you sure about that? If it did, that would be an astonishing bug. I 
cannot replicate the behaviour you describe:

py> posixpath.relpath("/a/b/c")
'../../a/b/c'


However, if you pass a path using \ to posixpath, it treats them as 
non-separators:

py> posixpath.relpath("\\a\\b\\c")
'\\a\\b\\c'


That's because the given path \a\b\c under POSIX represents a file named 
"backslash a backslash b backslash c" in the current directory, not a 
file named c in a directory b in a directory a.


If you still think this is an issue, can you Can you post a minimal set 
of code that demonstrates that problem? Also, please specify the Python 
version.


Thanks,



-- 
Steven

From missive at hotmail.com  Sat Jan 11 00:44:14 2014
From: missive at hotmail.com (Lee Harr)
Date: Sat, 11 Jan 2014 04:14:14 +0430
Subject: [Tutor] Python & Django
Message-ID: <BLU168-W6951F8117AA0073A6438E1B1B30@phx.gbl>

> I am very interested to hear your opinion on which version of Python
> to use in conjunction with Django. Currently, I am taking a class at
> Udemy and they recommend using Python 2.7 with Django 1.6. because
> both versions work well with each other.
>
> Over the last few months I got pretty much used to Python 3.3.0 which
> some of you guys recommended to me on this mailing list. Hence, I
> would prefer to keep using Python 3x but I am not sure if that's a
> good idea. I heard of a couple folks using Python 3.3.0 with Django
> 1.6 that they ran into issues, and most of them switched back to
> Python 2.7.


I am using django 1.6 with python 3.3 and have had no problems.

It depends on what other modules you depend on, but for me
everything I need is working well. 		 	   		  

From amydavidson at sympatico.ca  Sat Jan 11 02:57:34 2014
From: amydavidson at sympatico.ca (Amy Davidson)
Date: Fri, 10 Jan 2014 20:57:34 -0500
Subject: [Tutor] Python Question
In-Reply-To: <CAGZAPF41DH3cRjJVjtBzU93i=cKowptVf4eEtGixm+1trF1S0A@mail.gmail.com>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
 <CAGZAPF7vHKMf7-U1HT=mwjDdmOkYCnjk1MB3XiQ5SmPxjKhmQw@mail.gmail.com>
 <BLU0-SMTP335F2BC055B4B9C4C58094C8B30@phx.gbl>
 <CAGZAPF7JXiw=bXi0hv-xLCE5wgX2EJjoi8Y65kVEcU9sEieSWA@mail.gmail.com>
 <CAO5ffbaM88sfDfJnW=m=ixQK2PhUNm3ZppQo-NpaQGwpjZ9Esg@mail.gmail.com>
 <CAGZAPF41DH3cRjJVjtBzU93i=cKowptVf4eEtGixm+1trF1S0A@mail.gmail.com>
Message-ID: <BLU0-SMTP95E62CB472599E6784E98FC8B20@phx.gbl>

Hey Danny,

I just started taking the course (introduction to Computer Science) on last Tuesday, so I am not to familiar. I have been doing my best to understand  the material by reading the text book, Learn Python the hard way.

In my quest to answer the question given to me, I have searched the internet high and low of other functions thus, I am familiar with the basic knowledge of them (i.e. starting with def) as well as examples.

We can attempt the approach to the method that you prefer.

Thans for helping me, by the way. 
On Jan 10, 2014, at 5:25 PM, Danny Yoo <dyoo at hashcollision.org> wrote:

> On Fri, Jan 10, 2014 at 2:00 PM, Keith Winston <keithwins at gmail.com> wrote:
>> Amy, judging from Danny's replies, you may be emailing him and not the
>> list. If you want others to help, or to report on your progress,
>> you'll need to make sure the tutor email is in your reply to:
> 
> Hi Amy,
> 
> Very much so.  Please try to use "Reply to All" if you can.
> 
> If you're wondering why I'm asking for you to try to recall any other
> example function definitions, I'm doing so specifically because it is
> a general problem-solving technique.  Try to see if the problem that's
> stumping you is similar to things you've seen before.  Several of the
> heuristics from Polya's "How to Solve It" refer to this:
> 
>    http://en.wikipedia.org/wiki/How_to_Solve_It
> 
> If you haven't ever seen any function definition ever before, then we
> do have to start from square one.  But this would be a very strange
> scenario, to be asked to write a function definition without having
> seen any previous definitions before.
> 
> If you have seen a function before, then one approach we might take is
> try to make analogies to those previous examples.  That's an approach
> I'd prefer.
> 


From carroll at tjc.com  Sat Jan 11 01:06:57 2014
From: carroll at tjc.com (Terry Carroll)
Date: Fri, 10 Jan 2014 16:06:57 -0800 (PST)
Subject: [Tutor] How can a CGI program get the URL that called it?
In-Reply-To: <20140110234310.GL3869@ando>
References: <alpine.LRH.2.00.1401091420480.5902@aqua.rahul.net>
 <laoie6$vqp$1@ger.gmane.org>
 <alpine.LRH.2.00.1401101356290.28530@aqua.rahul.net>
 <20140110234310.GL3869@ando>
Message-ID: <alpine.LRH.2.00.1401101603410.28530@aqua.rahul.net>

On Sat, 11 Jan 2014, Steven D'Aprano wrote:

> However, if you pass a path using \ to posixpath, it treats them as
> non-separators:

That's apparenbtly what's happening.  I didn't investigate much, once I 
found out that using posixpath didn't address the issue I was having; 
using replace() was pretty straightforward.

From dyoo at hashcollision.org  Sat Jan 11 04:44:45 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 10 Jan 2014 19:44:45 -0800
Subject: [Tutor] Python Question
In-Reply-To: <BLU0-SMTP95E62CB472599E6784E98FC8B20@phx.gbl>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
 <CAGZAPF7vHKMf7-U1HT=mwjDdmOkYCnjk1MB3XiQ5SmPxjKhmQw@mail.gmail.com>
 <BLU0-SMTP335F2BC055B4B9C4C58094C8B30@phx.gbl>
 <CAGZAPF7JXiw=bXi0hv-xLCE5wgX2EJjoi8Y65kVEcU9sEieSWA@mail.gmail.com>
 <CAO5ffbaM88sfDfJnW=m=ixQK2PhUNm3ZppQo-NpaQGwpjZ9Esg@mail.gmail.com>
 <CAGZAPF41DH3cRjJVjtBzU93i=cKowptVf4eEtGixm+1trF1S0A@mail.gmail.com>
 <BLU0-SMTP95E62CB472599E6784E98FC8B20@phx.gbl>
Message-ID: <CAGZAPF7RtSch956jcX7MW+YzaTRzmtcXkfze6DdKMHic05jyuA@mail.gmail.com>

On Fri, Jan 10, 2014 at 5:57 PM, Amy Davidson <amydavidson at sympatico.ca> wrote:
> Hey Danny,
>
> I just started taking the course (introduction to Computer Science) on last Tuesday, so I am not to familiar. I have been doing my best to understand  the material by reading the text book, Learn Python the hard way.
>
> In my quest to answer the question given to me, I have searched the internet high and low of other functions thus, I am familiar with the basic knowledge of them (i.e. starting with def) as well as examples.

Great, ok.  So you're going through Learn Python the Hard Way.


I'm looking at the beginning of:

    http://learnpythonthehardway.org/book/ex19.html

Have you gotten that far yet?  I see a function at the beginning of
that section called cheese_and_crackers.

######################################################
def cheese_and_crackers(cheese_count, boxes_of_crackers):
    print "You have %d cheeses!" % cheese_count
    print "You have %d boxes of crackers!" % boxes_of_crackers
    print "Man that's enough for a party!"
    print "Get a blanket.\n"
######################################################

Can you tell me a little bit of how this function definition works?
What is the "%d" thing there?  What is cheese_count, and what is
box_of_crackers?

Have you been able to effectively type in this function and use it in
your Python programming environment?

Are there any similarities between what this function definition does,
and what your problem statement asks?

From daedae11 at 126.com  Sat Jan 11 05:48:13 2014
From: daedae11 at 126.com (daedae11)
Date: Sat, 11 Jan 2014 12:48:13 +0800 (CST)
Subject: [Tutor] Question about subprocess
Message-ID: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com>

p = subprocess.Popen(['E:/EntTools/360EntSignHelper.exe', 'E:/build/temp/RemoteAssistSetup.exe'],
                         stdout=subprocess.PIPE, shell=True).stdout
temp = p.readline();
print temp
p.close()

When I run the above code in command line, it works formally.

However, when I writed it into a .py file and execute the .py file, it blocked at "temp=p.readline()".

What's the problem?

Please help.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140111/ca7ab5a9/attachment-0001.html>

From dyoo at hashcollision.org  Sat Jan 11 06:46:52 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 10 Jan 2014 21:46:52 -0800
Subject: [Tutor] Question about subprocess
In-Reply-To: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com>
References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com>
Message-ID: <CAGZAPF43LUmU6OEbdTykXk6_W_uwX+H0eqQwPvhKhoEwDKnA4g@mail.gmail.com>

There is a warning in the documentation on subprocess that might be
relevant to your situation:

    Warning:
    Use communicate() rather than .stdin.write, .stdout.read or
.stderr.read to avoid deadlocks due to any of the other OS pipe
buffers filling up and blocking the child process.

Reference: http://docs.python.org/2/library/subprocess.html


It's possible that the process is deadlocking due to this situation.
Do you run into this issue if you use communicate()?



Good luck!

From steve at pearwood.info  Sat Jan 11 06:51:09 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 11 Jan 2014 16:51:09 +1100
Subject: [Tutor] Question about subprocess
In-Reply-To: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com>
References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com>
Message-ID: <20140111055109.GN3869@ando>

On Sat, Jan 11, 2014 at 12:48:13PM +0800, daedae11 wrote:
> p = subprocess.Popen(['E:/EntTools/360EntSignHelper.exe', 'E:/build/temp/RemoteAssistSetup.exe'],
>                          stdout=subprocess.PIPE, shell=True).stdout
> temp = p.readline();
> print temp
> p.close()
> 
> When I run the above code in command line, it works formally.

What do you mean, "the above code"? Do you mean the *Python* code? Or do 
you mean calling the 360EntSignHelper.exe application from the command 
line? I'm going to assume you mean calling the .exe.


> However, when I writed it into a .py file and execute the .py file, it blocked at "temp=p.readline()".

Of course it does. You haven't actually called the .exe file, all you 
have done is created a Popen instance and then grabbed a reference to 
it's stdout. Then you sit and wait for stdout to contain data, which it 
never does.

Instead, you can do this:

p = subprocess.Popen(['E:/EntTools/360EntSignHelper.exe', 
                      'E:/build/temp/RemoteAssistSetup.exe'],
                       stdout=subprocess.PIPE, shell=True)
output = p.communicate()[0]
print output


I think that should do what you expect.


-- 
Steven

From eryksun at gmail.com  Sat Jan 11 10:13:57 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 11 Jan 2014 04:13:57 -0500
Subject: [Tutor] Question about subprocess
In-Reply-To: <CAGZAPF43LUmU6OEbdTykXk6_W_uwX+H0eqQwPvhKhoEwDKnA4g@mail.gmail.com>
References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com>
 <CAGZAPF43LUmU6OEbdTykXk6_W_uwX+H0eqQwPvhKhoEwDKnA4g@mail.gmail.com>
Message-ID: <CACL+1asBB5vh3rWT8djt65HrR3qGzObT_R46HZ0qmbePm6StHg@mail.gmail.com>

On Sat, Jan 11, 2014 at 12:46 AM, Danny Yoo <dyoo at hashcollision.org> wrote:
> There is a warning in the documentation on subprocess that might be
> relevant to your situation:
>
>     Warning:
>     Use communicate() rather than .stdin.write, .stdout.read or
> .stderr.read to avoid deadlocks due to any of the other OS pipe
> buffers filling up and blocking the child process.
>
> Reference: http://docs.python.org/2/library/subprocess.html
>
> It's possible that the process is deadlocking due to this situation.
> Do you run into this issue if you use communicate()?

If more than one standard file is piped (not the case for the OP),
`communicate` avoids deadlocks by using `poll` or `select` on POSIX.
On Windows, it uses the current thread to write to stdin and uses
separate threads to read from stdout and stderr.

If only one standard file is piped, then there's no deadlock. It's
just blocked while waiting for the buffer to fill. `communicate` does
nothing special in this case (at least prior to 3.3):

http://hg.python.org/cpython/file/3a1db0d2747e/Lib/subprocess.py#l767

In 3.3, the new `timeout` option for `communicate` also uses the
select/thread implementation.

stdout FILE stream buffering could be a problem if output is
intermittent and the program doesn't `fflush` the buffer. On Linux the
`stdbuf` program may be able to circumvent this. It injects code (i.e.
libstdbuf.so is added to LD_PRELOAD) that calls `setvbuf` before the
target's `main` runs. This allows you to set the stream to line
buffering mode (unless the program itself calls `setvbuf`). I don't
think a similar utility exists on Windows.

http://linux.die.net/man/1/stdbuf

From eryksun at gmail.com  Sat Jan 11 10:26:00 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 11 Jan 2014 04:26:00 -0500
Subject: [Tutor] Question about subprocess
In-Reply-To: <20140111055109.GN3869@ando>
References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com>
 <20140111055109.GN3869@ando>
Message-ID: <CACL+1atmXJo6GLXDWGKhRyb7x12rjLxSp0kHRiH5cM5mbC-muA@mail.gmail.com>

On Sat, Jan 11, 2014 at 12:51 AM, Steven D'Aprano <steve at pearwood.info> wrote:
>
>> However, when I writed it into a .py file and execute the .py file, it
>> blocked at "temp=p.readline()".
>
> Of course it does. You haven't actually called the .exe file, all you
> have done is created a Popen instance and then grabbed a reference to
> it's stdout. Then you sit and wait for stdout to contain data, which it
> never does.

Popen.__init__ calls Popen._execute_child, which on Windows is defined
to call _subprocess.CreateProcess. So the issue can't be that the OP
hasn't "called the .exe".

From eryksun at gmail.com  Sat Jan 11 10:30:55 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 11 Jan 2014 04:30:55 -0500
Subject: [Tutor] Question about subprocess
In-Reply-To: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com>
References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com>
Message-ID: <CACL+1auJNP8vFek5j+_G+VXohyGK5w3bEopW8a3nqm7nxjcj0A@mail.gmail.com>

On Fri, Jan 10, 2014 at 11:48 PM, daedae11 <daedae11 at 126.com> wrote:
> p = subprocess.Popen(['E:/EntTools/360EntSignHelper.exe',
> 'E:/build/temp/RemoteAssistSetup.exe'],
>                          stdout=subprocess.PIPE, shell=True).stdout

Is 360EntSignHelper supposed to run RemoteAssistSetup as a child
process? Or rather is it that from the command line you're piping the
output from the former into the latter? You'll need to provide more
information about what you mean by running the code "in command line".

Some general suggestions:

Remove shell=True. There's no reason to involve the shell here.
subprocess hides the window when you use shell=True, so maybe that's
why you're using it. But you can do that by setting the startupinfo
parameter to the following:

    si = subprocess.STARTUPINFO()
    si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    si.wShowWindow = subprocess.SW_HIDE

Also, as a matter of style, `p` is a bad name for stdout. It's not an
instance of [P]open representing a process.

From steve at pearwood.info  Sat Jan 11 11:04:32 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 11 Jan 2014 21:04:32 +1100
Subject: [Tutor] Question about subprocess
In-Reply-To: <CACL+1atmXJo6GLXDWGKhRyb7x12rjLxSp0kHRiH5cM5mbC-muA@mail.gmail.com>
References: <4eb0f2f.1d21.1437fa0fc6f.Coremail.daedae11@126.com>
 <20140111055109.GN3869@ando>
 <CACL+1atmXJo6GLXDWGKhRyb7x12rjLxSp0kHRiH5cM5mbC-muA@mail.gmail.com>
Message-ID: <20140111100431.GO3869@ando>

On Sat, Jan 11, 2014 at 04:26:00AM -0500, eryksun wrote:
> On Sat, Jan 11, 2014 at 12:51 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> >
> >> However, when I writed it into a .py file and execute the .py file, it
> >> blocked at "temp=p.readline()".
> >
> > Of course it does. You haven't actually called the .exe file, all you
> > have done is created a Popen instance and then grabbed a reference to
> > it's stdout. Then you sit and wait for stdout to contain data, which it
> > never does.
> 
> Popen.__init__ calls Popen._execute_child, which on Windows is defined
> to call _subprocess.CreateProcess. So the issue can't be that the OP
> hasn't "called the .exe".

Thanks for the correction.


-- 
Steven

From chigga101 at gmail.com  Sat Jan 11 15:08:07 2014
From: chigga101 at gmail.com (Matthew Ngaha)
Date: Sat, 11 Jan 2014 14:08:07 +0000
Subject: [Tutor] Windows Install Issue
Message-ID: <CACzNyA14GoZZj6svEuhQ-UTdr6bWQSTCpUPNumxHAoRp=UVgWA@mail.gmail.com>

Hi I'm trying to install pyqt5.2 for Windows Vista (Python3.3). 1st i
need to install sip but i run into this issue.

after ./configure, a MAKEFILE is created. I'm supposed to do 'make'
and 'make install', but i get this cmd error:

C:\path>make
'make' is not recognized as an internal or external command,
operable program or batch file.

I'm not really sure what i should do?

From breamoreboy at yahoo.co.uk  Sat Jan 11 15:55:17 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sat, 11 Jan 2014 14:55:17 +0000
Subject: [Tutor] Windows Install Issue
In-Reply-To: <CACzNyA14GoZZj6svEuhQ-UTdr6bWQSTCpUPNumxHAoRp=UVgWA@mail.gmail.com>
References: <CACzNyA14GoZZj6svEuhQ-UTdr6bWQSTCpUPNumxHAoRp=UVgWA@mail.gmail.com>
Message-ID: <larm0l$32q$1@ger.gmane.org>

On 11/01/2014 14:08, Matthew Ngaha wrote:
> Hi I'm trying to install pyqt5.2 for Windows Vista (Python3.3). 1st i
> need to install sip but i run into this issue.
>
> after ./configure, a MAKEFILE is created. I'm supposed to do 'make'
> and 'make install', but i get this cmd error:
>
> C:\path>make
> 'make' is not recognized as an internal or external command,
> operable program or batch file.
>
> I'm not really sure what i should do?

On Windows finding a binary installer is always the first thing to do, 
makefiles indeed.  Go here 
http://www.riverbankcomputing.co.uk/software/pyqt/download5, find the 
section "Binary Packages" and this gives Windows 32 and 64 bit installers.

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

Mark Lawrence


From chigga101 at gmail.com  Sat Jan 11 16:24:32 2014
From: chigga101 at gmail.com (Matthew Ngaha)
Date: Sat, 11 Jan 2014 15:24:32 +0000
Subject: [Tutor] Windows Install Issue
In-Reply-To: <larm0l$32q$1@ger.gmane.org>
References: <CACzNyA14GoZZj6svEuhQ-UTdr6bWQSTCpUPNumxHAoRp=UVgWA@mail.gmail.com>
 <larm0l$32q$1@ger.gmane.org>
Message-ID: <CACzNyA01x5emvLi-_CxUuJLKLQUtvX1Zx=aObgQFiYFcFXKYaQ@mail.gmail.com>

On Sat, Jan 11, 2014 at 2:55 PM, Mark Lawrence <breamoreboy at yahoo.co.uk> wrote:
>
> On Windows finding a binary installer is always the first thing to do,
> makefiles indeed.  Go here
> http://www.riverbankcomputing.co.uk/software/pyqt/download5, find the
> section "Binary Packages" and this gives Windows 32 and 64 bit installers.
>
sorry i forgot to explain. i cant get the binary:
http://www.riverbankcomputing.co.uk/software/pyqt/download5

"""Unfortunately it is not possible to use both the PyQt4 and PyQt5
installers at the same time. If you wish to have both PyQt4 and PyQt5
installed at the same time you will need to build them yourself from
the source packages."""

after seeing this i thought it was better not to try it and maybe
currupt my files

From breamoreboy at yahoo.co.uk  Sat Jan 11 16:29:14 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sat, 11 Jan 2014 15:29:14 +0000
Subject: [Tutor] Windows Install Issue
In-Reply-To: <CACzNyA01x5emvLi-_CxUuJLKLQUtvX1Zx=aObgQFiYFcFXKYaQ@mail.gmail.com>
References: <CACzNyA14GoZZj6svEuhQ-UTdr6bWQSTCpUPNumxHAoRp=UVgWA@mail.gmail.com>
 <larm0l$32q$1@ger.gmane.org>
 <CACzNyA01x5emvLi-_CxUuJLKLQUtvX1Zx=aObgQFiYFcFXKYaQ@mail.gmail.com>
Message-ID: <laro0a$l69$1@ger.gmane.org>

On 11/01/2014 15:24, Matthew Ngaha wrote:
> On Sat, Jan 11, 2014 at 2:55 PM, Mark Lawrence <breamoreboy at yahoo.co.uk> wrote:
>>
>> On Windows finding a binary installer is always the first thing to do,
>> makefiles indeed.  Go here
>> http://www.riverbankcomputing.co.uk/software/pyqt/download5, find the
>> section "Binary Packages" and this gives Windows 32 and 64 bit installers.
>>
> sorry i forgot to explain. i cant get the binary:
> http://www.riverbankcomputing.co.uk/software/pyqt/download5
>
> """Unfortunately it is not possible to use both the PyQt4 and PyQt5
> installers at the same time. If you wish to have both PyQt4 and PyQt5
> installed at the same time you will need to build them yourself from
> the source packages."""
>
> after seeing this i thought it was better not to try it and maybe
> currupt my files

http://stackoverflow.com/questions/16846501/how-to-install-pyqt5-on-windows

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

Mark Lawrence


From wolfrage8765 at gmail.com  Sat Jan 11 18:26:04 2014
From: wolfrage8765 at gmail.com (wolfrage8765 at gmail.com)
Date: Sat, 11 Jan 2014 12:26:04 -0500
Subject: [Tutor] Python Question
In-Reply-To: <BLU0-SMTP95E62CB472599E6784E98FC8B20@phx.gbl>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
 <CAGZAPF7vHKMf7-U1HT=mwjDdmOkYCnjk1MB3XiQ5SmPxjKhmQw@mail.gmail.com>
 <BLU0-SMTP335F2BC055B4B9C4C58094C8B30@phx.gbl>
 <CAGZAPF7JXiw=bXi0hv-xLCE5wgX2EJjoi8Y65kVEcU9sEieSWA@mail.gmail.com>
 <CAO5ffbaM88sfDfJnW=m=ixQK2PhUNm3ZppQo-NpaQGwpjZ9Esg@mail.gmail.com>
 <CAGZAPF41DH3cRjJVjtBzU93i=cKowptVf4eEtGixm+1trF1S0A@mail.gmail.com>
 <BLU0-SMTP95E62CB472599E6784E98FC8B20@phx.gbl>
Message-ID: <CAOhNYvkKhic6AzbJ8+Yg73H_EVBn9wEmFMnSE3e-xEH085S9FQ@mail.gmail.com>

 It will also be helpful if you tell us your OS and Python Version.
Can you also tell us if you are writing the code to a file and
executing, using IDLE or some other IDE, or are you using the
interpreter interactively?

On Fri, Jan 10, 2014 at 8:57 PM, Amy Davidson <amydavidson at sympatico.ca> wrote:
> Hey Danny,
>
> I just started taking the course (introduction to Computer Science) on last Tuesday, so I am not to familiar. I have been doing my best to understand  the material by reading the text book, Learn Python the hard way.
>
> In my quest to answer the question given to me, I have searched the internet high and low of other functions thus, I am familiar with the basic knowledge of them (i.e. starting with def) as well as examples.
>
> We can attempt the approach to the method that you prefer.
>
> Thans for helping me, by the way.
> On Jan 10, 2014, at 5:25 PM, Danny Yoo <dyoo at hashcollision.org> wrote:
>
>> On Fri, Jan 10, 2014 at 2:00 PM, Keith Winston <keithwins at gmail.com> wrote:
>>> Amy, judging from Danny's replies, you may be emailing him and not the
>>> list. If you want others to help, or to report on your progress,
>>> you'll need to make sure the tutor email is in your reply to:
>>
>> Hi Amy,
>>
>> Very much so.  Please try to use "Reply to All" if you can.
>>
>> If you're wondering why I'm asking for you to try to recall any other
>> example function definitions, I'm doing so specifically because it is
>> a general problem-solving technique.  Try to see if the problem that's
>> stumping you is similar to things you've seen before.  Several of the
>> heuristics from Polya's "How to Solve It" refer to this:
>>
>>    http://en.wikipedia.org/wiki/How_to_Solve_It
>>
>> If you haven't ever seen any function definition ever before, then we
>> do have to start from square one.  But this would be a very strange
>> scenario, to be asked to write a function definition without having
>> seen any previous definitions before.
>>
>> If you have seen a function before, then one approach we might take is
>> try to make analogies to those previous examples.  That's an approach
>> I'd prefer.
>>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From amydavidson at sympatico.ca  Sat Jan 11 18:23:29 2014
From: amydavidson at sympatico.ca (Amy Davidson)
Date: Sat, 11 Jan 2014 12:23:29 -0500
Subject: [Tutor] Python Question
In-Reply-To: <aeb86253d987b15c7433a1bfd44447e3@sonic.net>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
 <CAGZAPF7vHKMf7-U1HT=mwjDdmOkYCnjk1MB3XiQ5SmPxjKhmQw@mail.gmail.com>
 <BLU0-SMTP335F2BC055B4B9C4C58094C8B30@phx.gbl>
 <CAGZAPF7JXiw=bXi0hv-xLCE5wgX2EJjoi8Y65kVEcU9sEieSWA@mail.gmail.com>
 <CAO5ffbaM88sfDfJnW=m=ixQK2PhUNm3ZppQo-NpaQGwpjZ9Esg@mail.gmail.com>
 <CAGZAPF41DH3cRjJVjtBzU93i=cKowptVf4eEtGixm+1trF1S0A@mail.gmail.com>
 <BLU0-SMTP95E62CB472599E6784E98FC8B20@phx.gbl>
 <aeb86253d987b15c7433a1bfd44447e3@sonic.net>
Message-ID: <BLU0-SMTP94D97BF9CB652B4C93F918C8B20@phx.gbl>

Hey!
So luckily with the texts that were sent to me, I was able to figure out the answer(yay)!

Unfortunately I am now stuck on a different question.

"Write a function called highlight() that prompts the user for a string.
Your code should ensure that the string is all lower case.
Next, prompt the user for a smaller 'substring' of one or more characters. 
Then replace every occurrence of the substring in the first string with an upper case.
Finally, report to the user how many changes were made (i.e., how many occurrences of the substring there were).?
On Jan 11, 2014, at 1:04 AM, Alex Kleider <akleider at sonic.net> wrote:

> On 2014-01-10 17:57, Amy Davidson wrote:
>> Hey Danny,
>> I just started taking the course (introduction to Computer Science) on
>> last Tuesday, so I am not to familiar. I have been doing my best to
>> understand  the material by reading the text book, Learn Python the
>> hard way.
> 
> A lot of people seem to think "the Hard Way" is the way to go.  I disagree.  I found that Allen Downey's book is excellent and free (although the book is also available in 'real' print which works better for me.)
> 
> http://www.greenteapress.com/thinkpython/
> 
> My copy covers Python 2.7, you use Python 3 I believe, but I doubt that that will be too much of a problem.  At the intro level the differences are few.
> 
> ak
> 
>> In my quest to answer the question given to me, I have searched the
>> internet high and low of other functions thus, I am familiar with the
>> basic knowledge of them (i.e. starting with def) as well as examples.
>> We can attempt the approach to the method that you prefer.
>> Thans for helping me, by the way.
>> On Jan 10, 2014, at 5:25 PM, Danny Yoo <dyoo at hashcollision.org> wrote:
>>> On Fri, Jan 10, 2014 at 2:00 PM, Keith Winston <keithwins at gmail.com> wrote:
>>>> Amy, judging from Danny's replies, you may be emailing him and not the
>>>> list. If you want others to help, or to report on your progress,
>>>> you'll need to make sure the tutor email is in your reply to:
>>> Hi Amy,
>>> Very much so.  Please try to use "Reply to All" if you can.
>>> If you're wondering why I'm asking for you to try to recall any other
>>> example function definitions, I'm doing so specifically because it is
>>> a general problem-solving technique.  Try to see if the problem that's
>>> stumping you is similar to things you've seen before.  Several of the
>>> heuristics from Polya's "How to Solve It" refer to this:
>>>   http://en.wikipedia.org/wiki/How_to_Solve_It
>>> If you haven't ever seen any function definition ever before, then we
>>> do have to start from square one.  But this would be a very strange
>>> scenario, to be asked to write a function definition without having
>>> seen any previous definitions before.
>>> If you have seen a function before, then one approach we might take is
>>> try to make analogies to those previous examples.  That's an approach
>>> I'd prefer.
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> https://mail.python.org/mailman/listinfo/tutor
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140111/ae7e6d2d/attachment-0001.html>

From stareq13 at yahoo.com  Sat Jan 11 15:52:07 2014
From: stareq13 at yahoo.com (S Tareq)
Date: Sat, 11 Jan 2014 14:52:07 +0000 (GMT)
Subject: [Tutor] need help
Message-ID: <1389451927.74792.YahooMailNeo@web133104.mail.ir2.yahoo.com>

how can i do this on python using py game:

?
Scenario?3:?BotMod
?
BotMod?is?a?game?where?a?player?has?to?guide?a?robot?through?a?landscape?to?collect?people?and?carry
them?to?a?base?camp?before?the?robot?s?power?runs?out.?The?landscape?is?represented?by?a?10?by?10
grid?and?contains?a?mixture?of?grassland,?rocks?and?ice.
?
The?robot?always?starts?in?the?top?left?square?of?the?grid.?The?player?can?move?the?robot?one?square?at
a?time?in?any?of?the?directions?shown?in?Figure?1.
?
Figure?1
 
?
?
?
?
?
?
?
?
?
?
 
The?robot?cannot:
????? make?diagonal?moves
????? move?beyond?any?edge?of?the?grid.
?
When?the?robot?moves?into?a?square?containing?a?person:
????? if?the?robot?has?space?in?its?passenger?bay,?the?person?is?automatically?picked?up
????? if?there?is?no?space?in?the?passenger?bay,?the?person?remains?in?the?square?and?is?not?picked
up.
?
When?the?robot?moves?into?the?square?containing?the?base?camp?all?of?the?people?in?the?robot?s
passenger?bay?are?automatically?unloaded.
?
The?robot?starts?with?150?power?units.
?
Before?the?player?begins?controlling?their?robot?they?should?modify?it?by?choosing?the:
????? type?of?traction?they?want?(wheels,?tracks?or?skis)
????? size?of?the?passenger?bay?(large,?medium?or?small).
?
These?modifications?affect?how?the?robot?operates?as?it?moves?around?the?different?types?of?terrain?in
the?landscape.?Different?choices?mean?that?different?amounts?of?power?will?be?used?by?the?robot?as?it
moves?around?the?landscape.?The?size?of?the?passenger?bay?also?determines?the?maximum?number?of
people?that?the?robot?can?carry?at?one?time.?Full?details?are?given?in?Tables?1?and?2?on?page?5.
?
After?each?move?made?by?the?robot?the?number?of:
????? passengers?being?carried?by?the?robot
????? power?units?the?robot?currently?has
should?be?displayed?to?the?player.
?
The?player?wins?the?game?when?all?of?the?people?are?dropped?off?at?the?base?camp?before?the?robot
runs?out?of?power.
?
The?landscape?and?initial?positions?of?the?robot,?people?and?base?camp?are?shown?in?Figure?2.
 
?
?
?
?
?
?
?
 
Scenario?3
 
R ? P ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? P ? ? 
? ? ? ? ? ? B ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? P ? ? ? ? P 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
Colour?of
square Type?of?terrain 
Green Grassland 
White Ice 
Brown Rocks 
Letter Object 
R The?robot 
P A?person 
B Base?camp 
?
?
 
3
?
Figure?2
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
Key
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
Turn?over??
?
Scenario?3
 
?
?
 
4
Tasks
?
1)?Develop?a?start?menu?for?the?game.?This?must?give?the?user?the?options?of?modifying?their?robot,
playing?the?game?or?exiting?the?program.
?
2)?Develop?the?part?of?the?program?where?the?player?modifies?their?robot.?The?player?should?be
able?to?select?their?choices?and?return?to?the?start?menu?when?they?have?finished.?They?should
be?able?to?make?the?following?choices:
?
????? type?of?traction?they?want?(wheels,?tracks?or?skis)
????? size?of?the?passenger?bay?(large,?medium?or?small).
?
3)?Develop?the?program?so?that?when?the?player?chooses?to?play?the?game?from?the?start?menu?the
landscape?and?initial?positions?of?the?robot,?people?and?base?camp?are?displayed?(as?shown?in
Figure?2).
?
4)?Develop?the?part?of?the?program?to?enable?the?player?to?move?the?robot?as?described?in
Figure?1.
?
5)?Develop?the?program?so?that?the?robot?automatically?picks?up?a?person?when?it?moves?into?the
square?they?are?occupying?if?there?is?enough?room?in?its?passenger?bay.?It?should?also
automatically?drop?off?all?its?passengers?when?it?moves?into?the?square?containing?the?base
camp.
?
6)?Develop?the?part?of?the?program?that?calculates?and?displays?the?power?units?and?number?of
passengers?after?each?move.?At?the?start?of?every?game?the?robot?should?have?150?power?units.
Refer?to?Tables?1?and?2?for?how?these?values?should?change?after?each?move.
?
7)?Develop?the?part?of?the?program?that?checks?if?the?player?has?won?or?lost?the?game.
a.?The?player?has?won?if?all?of?the?people?have?been?taken?to?the?base?camp.
b.?The?player?has?lost?if?the?number?of?power?units?runs?out.
c.?If?the?power?units?run?out?on?the?last?move?the?player?has?still?won.
When?the?player?finishes?a?game?a?relevant?message?should?be?displayed?and?they?should?be
returned?to?the?start?menu.
?
8)?Extend?the?program?by?creating?more?levels?for?the?game?that?increase?the?difficulty?for?the
player.?Each?time?a?player?wins?a?game,?they?move?up?a?level?and?the?robot?starts?with?fewer
power?units?than?on?the?previous?level.
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
Scenario?3
 
?
Traction?type Effect?when
moving?onto
grassland Effect?when
moving?onto
rocks Effect?when
moving?onto
ice 
?
Wheels Costs?1?power
unit Costs?2?power
units Costs?3?power
units 
?
Tracks Costs?3?power
units Costs?3?power
units Costs?3?power
units 
?
Skis Costs?3?power
units Costs?3?power
units Costs?1?power
unit 
Size?of?passenger
bay Maximum
passengers?at?any
one?time ?
Power?Cost 
Large?passenger?bay 3 Costs?2?additional?power
units?per?move 
Medium?passenger
bay ?
2 Costs?1?additional?power
unit?per?move 
Small?passenger?bay 1 Costs?0?additional?power
units?per?move 
?
?
 
5
?
Table?1
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
Table?2
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
Turn?over?for?an?example?of?the?game?in?action
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
?
Scenario?3
 
R ? P ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? P ? ? 
? ? ? ? ? ? B ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? P ? ? ? ? P 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
?
?
 
6
An?example?of?the?game?in?action
?
The?player?has?made?the?following?modifications?to?the?robot:
????? Traction?type:?wheels
????? Passenger?bay?size:?large
?
Number?of?passengers:?0
Power?units:?150
?
Move?1?(robot?moves?onto?grassland)
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
Wheels?cost?1?power?unit
Large?passenger?bay?costs?2?power?units
?
Number?of?passengers:?0
Power?units:?150???1???2?=?147
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
Scenario?3
 
 
? R P ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? P ? ? 
? ? ? ? ? ? B ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? P ? ? ? ? P 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? R ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? P ? ? 
? ? ? ? ? ? B ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? P ? ? ? ? P 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
?
?
 
7
Move?2?(robot?moves?onto?ice?to?collect?a?person)
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
Wheels?cost?3?power?units
Large?passenger?bay?costs?2?power?units
?
Number?of?passengers:?0?+?1?=?1
Power?units:?147???3???2?=?142
?
Move?3?(robot?moves?onto?rocks)
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
Wheels?cost?2?power?units
Large?passenger?bay?costs?2?power?units
?
Number?of?passengers:?1
Power?units:?142???2???2?=?138
 
?
?
?
 
?
 
 
? ? ? ? ? ? ? ? ? ? 
? ? R ? ? ? ? ? ? ? 
? ? ? ? ? ? ? P ? ? 
? ? ? ? ? ? B ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? P ? ? ? ? P 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
? ? ? ? ? ? ? ? ? ? 
?
?
 
8
 
?
 
Move?4?(robot?moves?onto?ice)
 
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
 
Wheels?cost?3?power?units
Large?passenger?bay?costs?2?power?units
?
Number?of?passengers:?1
Power?units:?138???3???2?=?133
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140111/cebb795c/attachment-0001.html>

From breamoreboy at yahoo.co.uk  Sat Jan 11 18:57:37 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sat, 11 Jan 2014 17:57:37 +0000
Subject: [Tutor] need help
In-Reply-To: <1389451927.74792.YahooMailNeo@web133104.mail.ir2.yahoo.com>
References: <1389451927.74792.YahooMailNeo@web133104.mail.ir2.yahoo.com>
Message-ID: <las0mi$ioq$1@ger.gmane.org>

On 11/01/2014 14:52, S Tareq wrote:
> how can i do this on python using py game:
>

No idea as what you've sent isn't readable when you try to reply. Also I 
can't see any code so sorry but I'm not doing your homework for you :(

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

Mark Lawrence


From badouglas at gmail.com  Sat Jan 11 19:03:02 2014
From: badouglas at gmail.com (bruce)
Date: Sat, 11 Jan 2014 13:03:02 -0500
Subject: [Tutor] Python Question
In-Reply-To: <BLU0-SMTP94D97BF9CB652B4C93F918C8B20@phx.gbl>
References: <BLU0-SMTP447576E76F1980B4A118C1C8B30@phx.gbl>
 <CAGZAPF7vHKMf7-U1HT=mwjDdmOkYCnjk1MB3XiQ5SmPxjKhmQw@mail.gmail.com>
 <BLU0-SMTP335F2BC055B4B9C4C58094C8B30@phx.gbl>
 <CAGZAPF7JXiw=bXi0hv-xLCE5wgX2EJjoi8Y65kVEcU9sEieSWA@mail.gmail.com>
 <CAO5ffbaM88sfDfJnW=m=ixQK2PhUNm3ZppQo-NpaQGwpjZ9Esg@mail.gmail.com>
 <CAGZAPF41DH3cRjJVjtBzU93i=cKowptVf4eEtGixm+1trF1S0A@mail.gmail.com>
 <BLU0-SMTP95E62CB472599E6784E98FC8B20@phx.gbl>
 <aeb86253d987b15c7433a1bfd44447e3@sonic.net>
 <BLU0-SMTP94D97BF9CB652B4C93F918C8B20@phx.gbl>
Message-ID: <CAP16ngqJDuJDh26Ckpqc7pr30LXsPVAPj6UwOQyS76g7mg6E6g@mail.gmail.com>

hey amy..

ok.. before we jump to coding (and forgive me if what I'm about to
type is really basic!) let's play a bit with what's called
psuedo-code.

psuedo-code is a technique to kind of put your thoughts about a
problem/approach in a hash of code/english.. kind of lets you lay out
what you're trying to solve/program.

so for you issue:

you need to think about what you're trying to do.

you want to give the user back something, based on you doing something
to the thing the user gives you.

so this means, you need some way of getting user input
you want to do something to the input, so you need some way of
"capturing" the input to perform the "something" (better known as an
operation) on the user's input..

then you want to redisplay stuff back to the user, so you're going to
need a way of displaying back to the user the data/output..

create the psuedo-code, post it, and we'll get this in no time!



On Sat, Jan 11, 2014 at 12:23 PM, Amy Davidson <amydavidson at sympatico.ca> wrote:
> Hey!
> So luckily with the texts that were sent to me, I was able to figure out the
> answer(yay)!
>
> Unfortunately I am now stuck on a different question.
>
> "Write a function called highlight() that prompts the user for a string.
> Your code should ensure that the string is all lower case.
> Next, prompt the user for a smaller 'substring' of one or more characters.
> Then replace every occurrence of the substring in the first string with an
> upper case.
> Finally, report to the user how many changes were made (i.e., how many
> occurrences of the substring there were).?
> On Jan 11, 2014, at 1:04 AM, Alex Kleider <akleider at sonic.net> wrote:
>
> On 2014-01-10 17:57, Amy Davidson wrote:
>
> Hey Danny,
> I just started taking the course (introduction to Computer Science) on
> last Tuesday, so I am not to familiar. I have been doing my best to
> understand  the material by reading the text book, Learn Python the
> hard way.
>
>
> A lot of people seem to think "the Hard Way" is the way to go.  I disagree.
> I found that Allen Downey's book is excellent and free (although the book is
> also available in 'real' print which works better for me.)
>
> http://www.greenteapress.com/thinkpython/
>
> My copy covers Python 2.7, you use Python 3 I believe, but I doubt that that
> will be too much of a problem.  At the intro level the differences are few.
>
> ak
>
> In my quest to answer the question given to me, I have searched the
> internet high and low of other functions thus, I am familiar with the
> basic knowledge of them (i.e. starting with def) as well as examples.
> We can attempt the approach to the method that you prefer.
> Thans for helping me, by the way.
> On Jan 10, 2014, at 5:25 PM, Danny Yoo <dyoo at hashcollision.org> wrote:
>
> On Fri, Jan 10, 2014 at 2:00 PM, Keith Winston <keithwins at gmail.com> wrote:
>
> Amy, judging from Danny's replies, you may be emailing him and not the
> list. If you want others to help, or to report on your progress,
> you'll need to make sure the tutor email is in your reply to:
>
> Hi Amy,
> Very much so.  Please try to use "Reply to All" if you can.
> If you're wondering why I'm asking for you to try to recall any other
> example function definitions, I'm doing so specifically because it is
> a general problem-solving technique.  Try to see if the problem that's
> stumping you is similar to things you've seen before.  Several of the
> heuristics from Polya's "How to Solve It" refer to this:
>   http://en.wikipedia.org/wiki/How_to_Solve_It
> If you haven't ever seen any function definition ever before, then we
> do have to start from square one.  But this would be a very strange
> scenario, to be asked to write a function definition without having
> seen any previous definitions before.
> If you have seen a function before, then one approach we might take is
> try to make analogies to those previous examples.  That's an approach
> I'd prefer.
>
> _______________________________________________
> 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 wprins at gmail.com  Sat Jan 11 19:27:28 2014
From: wprins at gmail.com (Walter Prins)
Date: Sat, 11 Jan 2014 18:27:28 +0000
Subject: [Tutor] need help
In-Reply-To: <1389451927.74792.YahooMailNeo@web133104.mail.ir2.yahoo.com>
References: <1389451927.74792.YahooMailNeo@web133104.mail.ir2.yahoo.com>
Message-ID: <CANLXbfD5Khry80hLjTyzRyoJQfZHy+R_=g=BjvV-Gu7sYYp0jw@mail.gmail.com>

Hi,


On 11 January 2014 14:52, S Tareq <stareq13 at yahoo.com> wrote:

> how can i do this on python using py game:
>
>
You need to tell us more about what you've tried and where you're stuck.
Needless to say we're not a solution provision service, but we'd be happy
to help you get unstuck if you've already done some programming and have
gotten to a point where you're actually stuck.  :)

For the reference of others, I've managed to track down the full task
description here:
http://www.kirkbiekendal.cumbria.sch.uk/index.php/public-documents/school/general-information?download=339:2014-component-1-gaming-scenario-candidate-booklet

As this is therefore clearly homework that you'll be handing in, please
note we absolutely cannot provide you with concrete solutions to this
assignment.

As to your reference to PyGame -- I'd like to gently suggest that perhaps
you should not worry about PyGame if you're just starting out.  You can get
started without it and build a more basic solution first (maybe just simple
text mode) and then deal with whether you want to enhance/modify your
solution to use PyGame at some later time.

Walter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140111/ec45885f/attachment.html>

From reuben.dlink at gmail.com  Sat Jan 11 19:53:30 2014
From: reuben.dlink at gmail.com (Reuben)
Date: Sun, 12 Jan 2014 00:23:30 +0530
Subject: [Tutor] python query
Message-ID: <CAN89AcpvtrRsnOMwx3XCwS-jy-dps=nmxzk0aEpXjYYkS-dPww@mail.gmail.com>

Hi All,

I would like to know the difference between GUI programming v/s web
designing...To be more specific lets compare Django(used for web
programming) v/s Tkinter(used for GUI programming)


I wish to have a more clear difference regarding this.

Regards,
Reuben
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140112/5a858508/attachment.html>

From alan.gauld at btinternet.com  Sat Jan 11 22:26:41 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 11 Jan 2014 21:26:41 +0000
Subject: [Tutor] python query
In-Reply-To: <CAN89AcpvtrRsnOMwx3XCwS-jy-dps=nmxzk0aEpXjYYkS-dPww@mail.gmail.com>
References: <CAN89AcpvtrRsnOMwx3XCwS-jy-dps=nmxzk0aEpXjYYkS-dPww@mail.gmail.com>
Message-ID: <lascu5$grk$1@ger.gmane.org>

On 11/01/14 18:53, Reuben wrote:

> I would like to know the difference between GUI programming v/s web
> designing...To be more specific lets compare Django(used for web
> programming) v/s Tkinter(used for GUI programming)

What do you mean by the difference in programming? Do you want to know 
about the programming paradigms or the difference in deployment or the 
difference in the nature of the apps (I hope you already understand that 
but maybe not...)

Django is on the web so all the interactions take place over a network. 
The UI is displayed in a browser which interprets HTML sent from the 
server. Because of the relatively long latency between client and server 
web apps tend to be slower and less responsive than
desktop apps. To get round that they tend to cram more into a single 
screen. More modern apps also move a lot of functionality into 
Javascript on the browser and rely on lightweight protocols like JSON to 
fetch data from the server(this is known as Ajax style programming)

Tkinter is a desktop GUI toolkit where the application responds to users 
events and draws pictures(widgets) on the screen. All logic
and display happens locally, although some apps communicate with a 
server somewhere (this is called client server design).

OK, That's a start, what specifically do you want beyond that?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From jreh.val at gmail.com  Sun Jan 12 01:17:01 2014
From: jreh.val at gmail.com (Jerry Val)
Date: Sat, 11 Jan 2014 16:17:01 -0800
Subject: [Tutor] Tutor Digest, Vol 115, Issue 28
In-Reply-To: <mailman.2095.1379016934.5460.tutor@python.org>
References: <mailman.2095.1379016934.5460.tutor@python.org>
Message-ID: <CAKSTmRDWd0rZrp-rTUmzzVLyFH1D4ZPb+4G4__o+LAWp0psvYQ@mail.gmail.com>

I am trying to perfect myself in creating functions and looping, am using
python 3,can you help me with a few basic tips so i can create my own
functions and loops without making random mistakes?!
 On Sep 12, 2013 11:19 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: class data member and objects of class in python
>       (Felix Dietrich)
>    2. Re: class data member and objects of class in python (zubair alam)
>    3. Re: class data member and objects of class in python (Alan Gauld)
>    4. Re: Tutor Digest, Vol 115, Issue 27 (Dino Bekte?evi?)
>    5. Re: class data member and objects of class in python (Dave Angel)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Thu, 12 Sep 2013 02:59:51 +0200
> From: Felix Dietrich <felix.dietrich at sperrhaken.name>
> To: tutor at python.org
> Subject: Re: [Tutor] class data member and objects of class in python
> Message-ID: <87hadqx3aw.fsf at sperrhaken.name>
> Content-Type: text/plain
>
> > i am learning how a __class__ data member behaves in python as
> > compared to static data member in java [...]
>
> The error is not related to class variables. Also could you elaborate on
> what you intended to find out with this snippet?
>
> > class PizzaShop():
> >     pizza_stock = 10
> >
> >     def get_pizza(self):
> >         while not PizzaShop.pizza_stock:
> >             PizzaShop.pizza_stock -= 1
> >             yield "take yours pizza order, total pizzas left
> {}".format(PizzaShop.pizza_stock)
>
> The condition in the while loop is wrong. bool(PizzaShop.pizza_stock) is
> True for all values but 0. (All numbers but 0 are considered True.) The
> while loop does its commands while the condition holds True. When you do
>
> not PizzaShop.pizza_stock
>
> it will return False for values other than 0, therefor the loop is never
> run and on exit of get_pizza it raises StopIteration to indicate that
> there are no more values to be yielded.
>
> > mypizza_shop = PizzaShop()
> > pizza_order = mypizza_shop.get_pizza() # iterator is obtained
> > print "a pizza pls!! {}:".format(pizza_order.next())
> > print "a pizza pls!! {}:".format(pizza_order.next())
>
> You might want to catch StopIteration here so that you can handle the
> case that the shop runs out of the initial stack of pizzas. ;)
>
> --
> Felix Dietrich
>
>
> ------------------------------
>
> Message: 2
> Date: Thu, 12 Sep 2013 14:40:08 +0530
> From: zubair alam <zubair.alam.jmi at gmail.com>
> To: Marc Tompkins <marc.tompkins at gmail.com>
> Cc: tutor <tutor at python.org>
> Subject: Re: [Tutor] class data member and objects of class in python
> Message-ID:
>         <
> CAGqeC76+uN1_+yw3UC78f10nJ8usZDPGTd90JnBkUXpo2BaD1g at mail.gmail.com>
> Content-Type: text/plain; charset="iso-8859-1"
>
> class PizzaShop():
>     pizza_stock = 10
>     def get_pizza(self):
>         while PizzaShop.pizza_stock:
>             PizzaShop.pizza_stock -= 1
>             yield "take yours pizza order, total pizzas left
> {}".format(PizzaShop.pizza_stock)
>
> mypizza_shop = PizzaShop()
> pizza_order = mypizza_shop.get_pizza()
> # print "{}".format(repr(pizza_order.next()))
>
> for order in pizza_order:
> print "{}".format(repr(order))
>
> domino_pizza_store = mypizza_shop.get_pizza()
> print "{}".format(repr(domino_pizza_store.next()))
>
> mypizza_shop.pizza_stock = 10
>
> domino_pizza_store = mypizza_shop.get_pizza()
> print "{}".format(repr(domino_pizza_store.next()))
>
>
> can't we again use the same object mypizza_shop once its generator is
> exhausted
>
>
> On Thu, Sep 12, 2013 at 6:53 AM, Marc Tompkins <marc.tompkins at gmail.com
> >wrote:
>
> > On Wed, Sep 11, 2013 at 5:40 AM, zubair alam <zubair.alam.jmi at gmail.com
> >wrote:
> >
> >> i am learning how a __class__ data member behaves in python as compared
> >> to static data member in java, but following code is throwing error
> >>
> >>
> >> class PizzaShop():
> >>     pizza_stock = 10
> >>     def get_pizza(self):
> >>         while not PizzaShop.pizza_stock:
> >>             PizzaShop.pizza_stock -= 1
> >>             yield "take yours pizza order, total pizzas left
> >> {}".format(PizzaShop.pizza_stock)
> >>
> >> mypizza_shop = PizzaShop()
> >> pizza_order = mypizza_shop.get_pizza() # iterator is obtained
> >> print "a pizza pls!! {}:".format(pizza_order.next())
> >> print "a pizza pls!! {}:".format(pizza_order.next())
> >>
> >> output:
> >> Traceback (most recent call last):
> >>   File "/home/scott/pythonfiles/core_python/pizza.py", line 10, in
> >> <module>
> >>     print "a pizza pls!! {}:".format(pizza_order.next())
> >> StopIteration
> >>
> >>
> >> don't know where i am doing mistake....any help will be appreciated... i
> >> have other questions on based on this class
> >>
> >>
> >
> > Change "while not PizzaShop.pizza_stock:" to "while
> > PizzaShop.pizza_stock:"; I get the following output:
> >
> >> a pizza pls!! take yours pizza order, total pizzas left 9:
> >> a pizza pls!! take yours pizza order, total pizzas left 8:
> >>
> >
> >
> >
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <
> http://mail.python.org/pipermail/tutor/attachments/20130912/51dbe3d1/attachment-0001.html
> >
>
> ------------------------------
>
> Message: 3
> Date: Thu, 12 Sep 2013 14:39:53 +0100
> From: Alan Gauld <alan.gauld at btinternet.com>
> To: tutor at python.org
> Subject: Re: [Tutor] class data member and objects of class in python
> Message-ID: <l0sg71$qau$1 at ger.gmane.org>
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>
> On 12/09/13 10:10, zubair alam wrote:
> > class PizzaShop():
> >      pizza_stock = 10
> >      def get_pizza(self):
> >          while PizzaShop.pizza_stock:
> >              PizzaShop.pizza_stock -= 1
> >              yield "take yours pizza order, total pizzas left
> > {}".format(PizzaShop.pizza_stock)
> >
> > mypizza_shop = PizzaShop()
> > pizza_order = mypizza_shop.get_pizza()
> >
> > for order in pizza_order:
> > print "{}".format(repr(order))
>
> You might as well just use
>
> print order
>
> > domino_pizza_store = mypizza_shop.get_pizza()
> > print "{}".format(repr(domino_pizza_store.next()))
> >
> > mypizza_shop.pizza_stock = 10
>
> This preobably isn't doing what you think it is.
> This is creating a new instance attribute in the
> mypizza_shop instance it is not resetting the
> class attribute. For that you would need to use
>
> PizzaShop.pizza_stock = 10
>
> > can't we again use the same object mypizza_shop
>  > once its generator is exhausted
>
> You can't use the same iterator again but you can
> get a new one. But your problem here is that you have
> not reset the class stock level.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.flickr.com/photos/alangauldphotos
>
>
>
> ------------------------------
>
> Message: 4
> Date: Thu, 12 Sep 2013 14:25:05 +0200
> From: Dino Bekte?evi? <ljetibo at gmail.com>
> To: tutor at python.org
> Subject: Re: [Tutor] Tutor Digest, Vol 115, Issue 27
> Message-ID:
>         <CAMGeA2UUmC9N=
> T8thyKNNmsS1K6A7C1RwHDiaxz4_oc2G7OV3A at mail.gmail.com>
> Content-Type: text/plain; charset=ISO-8859-1
>
> > Date: Wed, 11 Sep 2013 18:10:18 +0530
> > From: zubair alam <zubair.alam.jmi at gmail.com>
> > To: tutor <tutor at python.org>
> > Subject: [Tutor] class data member and objects of class in python
> > Message-ID:
> >         <
> CAGqeC75oz8g8d2ibBwiCDFdGQdb65SYtDXKqfwVj8c2bP1OQqA at mail.gmail.com>
> > Content-Type: text/plain; charset="iso-8859-1"
> >
> > i am learning how a __class__ data member behaves in python as compared
> to
> > static data member in java, but following code is throwing error
> >
> >
> > class PizzaShop():
> >     pizza_stock = 10
> >     def get_pizza(self):
> >         while not PizzaShop.pizza_stock:
> >             PizzaShop.pizza_stock -= 1
> >             yield "take yours pizza order, total pizzas left
> > {}".format(PizzaShop.pizza_stock)
> >
> > mypizza_shop = PizzaShop()
> > pizza_order = mypizza_shop.get_pizza() # iterator is obtained
> > print "a pizza pls!! {}:".format(pizza_order.next())
> > print "a pizza pls!! {}:".format(pizza_order.next())
> >
> > output:
> > Traceback (most recent call last):
> >   File "/home/scott/pythonfiles/core_python/pizza.py", line 10, in
> <module>
> >     print "a pizza pls!! {}:".format(pizza_order.next())
> > StopIteration
> >
> >
> > don't know where i am doing mistake....any help will be appreciated... i
> > have other questions on based on this class
>
> Integers different from zero are considered to be True. So what you're
> basically doing is:
>       >>> pizza_stock=10
>       >>> while not pizza_stock:0 ## not True == False
>
> so the loop never runs, not even once. Python reports an error because
> of that. Similar reports occur if you have variables that are not used
> but those are Warnings and not actual Error events.
>
> Regards,
> Dino
>
>
> ------------------------------
>
> Message: 5
> Date: Thu, 12 Sep 2013 20:15:11 +0000 (UTC)
> From: Dave Angel <davea at davea.name>
> To: tutor at python.org
> Subject: Re: [Tutor] class data member and objects of class in python
> Message-ID: <l0t7cd$uk5$1 at ger.gmane.org>
> Content-Type: text/plain; charset=ISO-8859-1
>
> On 12/9/2013 05:10, zubair alam wrote:
>
>
> > <div dir="ltr"><div>class PizzaShop():</div><div>? ? pizza_stock =
> 10</div><div>? ? def get_pizza(self):</div><div>? ? ? ? while
> PizzaShop.pizza_stock:</div><div>? ? ? ? ? ? PizzaShop.pizza_stock -=
> 1</div><div>? ? ? ? ? ? yield &quot;take yours pizza order, total pizzas
> left {}&quot;.format(PizzaShop.pizza_stock)</div>
> > <div><br></div><div>mypizza_shop = PizzaShop()</div><div>pizza_order =
> mypizza_shop.get_pizza()?</div><div># print
> &quot;{}&quot;.format(repr(pizza_order.next()))</div><div><br></div><div>for
> order in pizza_order:</div><div>
> > <span class="" style="white-space:pre">       </span>print
> &quot;{}&quot;.format(repr(order))</div><div><br></div><div>domino_pizza_store
> = mypizza_shop.get_pizza()</div><div>print
> &quot;{}&quot;.format(repr(domino_pizza_store.next()))</div>
> > <div><br></div><div>mypizza_shop.pizza_stock =
> 10</div><div><br></div><div>domino_pizza_store =
> mypizza_shop.get_pizza()</div><div>print
> &quot;{}&quot;.format(repr(domino_pizza_store.next()))</div><div><br></div><div><br>
> > </div><div>can&#39;t we again use the same object mypizza_shop once its
> generator is exhausted</div></div><div class="gmail_extra"><br><br><div
> class="gmail_quote">On Thu, Sep 12, 2013 at 6:53 AM, Marc Tompkins <span
> dir="ltr">&lt;<a href="mailto:marc.tompkins at gmail.com" target="_blank">
> marc.tompkins at gmail.com</a>&gt;</span> wrote:<br>
>
> Please use text email, not hmtl.  The indentation of your program was
> messed up in places, and I can't tell whether it was you or the email
> program that messed it up.  This is a text newgroup, and html doesn't
> work reliably.
>
> As Alan has said, you're confusing class attributes with instance
> attributes.  But I wonder if the mistake is actually the reverse of what
> he says.
>
> Do you intend that an instance of PizzaShop refers to a particul pizza
> shop, and that it has its own inventory, independent of all other pizza
> shop instances?  in that case all use of the class attribute
> pizza_stock = 10 is bogus.
>
> To re-iterate the other point Alan made, an iterator is *required* to
> continue to throw Stopiteration once its exhausted and has thrown it
> once, even if new items show up that it could have used.
>
> But you can readily make a new iterator from the same mypizza_shop, once
> you set its pizza_stock to a nonzero value.
>
> --
> DaveA
>
>
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> https://mail.python.org/mailman/listinfo/tutor
>
>
> ------------------------------
>
> End of Tutor Digest, Vol 115, Issue 28
> **************************************
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140111/54e49318/attachment-0001.html>

From rwobben at hotmail.com  Sat Jan 11 22:24:56 2014
From: rwobben at hotmail.com (Roelof Wobben)
Date: Sat, 11 Jan 2014 21:24:56 +0000
Subject: [Tutor] another better way to do this ?
Message-ID: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>

Hello, 
 
I try to learn python by following the audicity page.
 
Now I have the following problem.
 
I have two strings a and b 
 
Now I have to check if the characters of b are all in a.
But they do have to be in the same order. 
 
So I thought about this solution.
 
length = len(b)
start = 1 
while start < length :
      check = a.find (b[start])
      if check == -1 : 
            return False 
      start = start + 1 
return True 
 
But according to the site this can be solved in a one-liner. 
 
So can someone give me pointers how this can be done and if my solution can work. 
 
Roelof
 
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140111/9eca37a9/attachment.html>

From alan.gauld at btinternet.com  Sun Jan 12 01:37:12 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 12 Jan 2014 00:37:12 +0000
Subject: [Tutor] Tutor Digest, Vol 115, Issue 28
In-Reply-To: <CAKSTmRDWd0rZrp-rTUmzzVLyFH1D4ZPb+4G4__o+LAWp0psvYQ@mail.gmail.com>
References: <mailman.2095.1379016934.5460.tutor@python.org>
 <CAKSTmRDWd0rZrp-rTUmzzVLyFH1D4ZPb+4G4__o+LAWp0psvYQ@mail.gmail.com>
Message-ID: <laso3c$qc3$1@ger.gmane.org>

On 12/01/14 00:17, Jerry Val wrote:
> I am trying to perfect myself in creating functions and looping, am
> using python 3,can you help me with a few basic tips so i can create my
> own functions and loops without making random mistakes?!

Please set a meaningful subject line, it makes finding posts in the 
archive much easier.

Also do not send the full digest content.
a) Most folks have already received the messages and don't want to see 
them, again
b) some folks pay for their bandwidth and don't want to pay for stuff 
they don't need
c) it obscures your message. Always cut it down to the lines that are 
pertinent. That way you are more likely to get sensible answers.

And for bonus points put your question after the cited context. Most 
readers prefer that to so called top posting.

As to your question. The best advice is to read what you type
carefully.
And know what you are trying to do before you type it.
In other words, think about the design of your code don't
just type randomly. That way you are less likely to
get random errors.

Other than that we will need some more specifics about what kind of 
errors you are getting. Usually most folks make the same kind of errors 
over and over. But the kind varies by individual. So until we know your 
style we can't help much.

HTH,
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From breamoreboy at yahoo.co.uk  Sun Jan 12 01:40:20 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 12 Jan 2014 00:40:20 +0000
Subject: [Tutor] Basic tips - was Re: Tutor Digest, Vol 115, Issue 28
In-Reply-To: <CAKSTmRDWd0rZrp-rTUmzzVLyFH1D4ZPb+4G4__o+LAWp0psvYQ@mail.gmail.com>
References: <mailman.2095.1379016934.5460.tutor@python.org>
 <CAKSTmRDWd0rZrp-rTUmzzVLyFH1D4ZPb+4G4__o+LAWp0psvYQ@mail.gmail.com>
Message-ID: <laso9l$s7j$1@ger.gmane.org>

On 12/01/2014 00:17, Jerry Val wrote:
> I am trying to perfect myself in creating functions and looping, am
> using python 3,can you help me with a few basic tips so i can create my
> own functions and loops without making random mistakes?!
>

IMHO the most important thing is to try your code snippets at the 
interactive prompt.  The second most important thing to get help here is 
*NOT* to reply to a four month old digest without changing the title, 
and worse still sending the whole completely irrelevant contents.

-- 
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 Jan 12 01:45:11 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 12 Jan 2014 00:45:11 +0000
Subject: [Tutor] another better way to do this ?
In-Reply-To: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
Message-ID: <lasoib$uo9$1@ger.gmane.org>

On 11/01/14 21:24, Roelof Wobben wrote:

> I have two strings a and b
>
> Now I have to check if the characters of b are all in a.
> But they do have to be in the same order.

I'm not sure exactly what you mean? Can you give some examples of
data that pass and that fail the criteria?

Your algorithm below might meet one definition of the spec but
its not valid code since it uses return but is not a function.

> length = len(b)
> start = 1
> while start < length :
>        check = a.find (b[start])
>        if check == -1 :
>              return False
>        start = start + 1
> return True

Problems I see are:
1) you start testing at b[1] not b[0]
2) you don't check if the letters are in the same sequence in a as in b
3) you probably could tidy it up using a for loop over b rather than 
indexing

> But according to the site this can be solved in a one-liner.

That depends on the spec.
And have you covered regular expressions? That is probably one
way to do a one-liner...

But just because you can do it in one line doesn't mean you
should. It's better for code to be readable than short.


HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From eryksun at gmail.com  Sun Jan 12 02:13:59 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 11 Jan 2014 20:13:59 -0500
Subject: [Tutor] Windows Install Issue
In-Reply-To: <CACzNyA01x5emvLi-_CxUuJLKLQUtvX1Zx=aObgQFiYFcFXKYaQ@mail.gmail.com>
References: <CACzNyA14GoZZj6svEuhQ-UTdr6bWQSTCpUPNumxHAoRp=UVgWA@mail.gmail.com>
 <larm0l$32q$1@ger.gmane.org>
 <CACzNyA01x5emvLi-_CxUuJLKLQUtvX1Zx=aObgQFiYFcFXKYaQ@mail.gmail.com>
Message-ID: <CACL+1atOU6-ubbjAzLGSBeiq4j1zArRygJtdUK3pJrVXp3fFvg@mail.gmail.com>

On Sat, Jan 11, 2014 at 10:24 AM, Matthew Ngaha <chigga101 at gmail.com> wrote:
>
> """Unfortunately it is not possible to use both the PyQt4 and PyQt5
> installers at the same time. If you wish to have both PyQt4 and PyQt5
> installed at the same time you will need to build them yourself from
> the source packages."""
>
> after seeing this i thought it was better not to try it and maybe
> currupt my files

The pre-built versions of PyQt4 and PyQt5 don't use the same version
of SIP. If you don't have a build system (e.g. Visual Studio 2010, the
Windows 7 SDK, or MinGW), then using a virtual environment should work
around the problem.

http://docs.python.org/3/library/venv.html

Install PyQt4, and then copy the following files and directories to a
separate environment:

    Python33\qt.conf
    Python33\Lib\site-packages\sip.pyd
    Python33\Lib\site-packages\PyQt4

Copy the qt.conf file to the environment's Scripts, and update the
absolute paths it contains to the new PyQt4 directory. Also edit
qt.conf and pyuic4.bat in the PyQt4 directory. Then uninstall PyQt4
and install PyQt5.

This would be simpler if PyQt used a bdist_wininst installer that
works with easy_install. Apparently PySide does.

From chigga101 at gmail.com  Sun Jan 12 03:04:28 2014
From: chigga101 at gmail.com (Matthew Ngaha)
Date: Sun, 12 Jan 2014 02:04:28 +0000
Subject: [Tutor] Windows Install Issue
In-Reply-To: <CACL+1atOU6-ubbjAzLGSBeiq4j1zArRygJtdUK3pJrVXp3fFvg@mail.gmail.com>
References: <CACzNyA14GoZZj6svEuhQ-UTdr6bWQSTCpUPNumxHAoRp=UVgWA@mail.gmail.com>
 <larm0l$32q$1@ger.gmane.org>
 <CACzNyA01x5emvLi-_CxUuJLKLQUtvX1Zx=aObgQFiYFcFXKYaQ@mail.gmail.com>
 <CACL+1atOU6-ubbjAzLGSBeiq4j1zArRygJtdUK3pJrVXp3fFvg@mail.gmail.com>
Message-ID: <CACzNyA13s7ymM1e4W1O8DZZsHunzQ-PqKKjJpQ_zp0yWVPNz7Q@mail.gmail.com>

On Sun, Jan 12, 2014 at 1:13 AM, eryksun <eryksun at gmail.com> wrote:

> The pre-built versions of PyQt4 and PyQt5 don't use the same version
> of SIP. If you don't have a build system (e.g. Visual Studio 2010, the
> Windows 7 SDK, or MinGW), then using a virtual environment should work
> around the problem.
>
> http://docs.python.org/3/library/venv.html
>
> Install PyQt4, and then copy the following files and directories to a
> separate environment:

Problem solved. Thanks so much:)

From dfjennings at gmail.com  Sun Jan 12 01:47:57 2014
From: dfjennings at gmail.com (Don Jennings)
Date: Sat, 11 Jan 2014 19:47:57 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
Message-ID: <688D63B0-1D22-4C5A-9B57-27A8EA4E2AF5@gmail.com>


On Jan 11, 2014, at 4:24 PM, Roelof Wobben wrote:

> Hello, 
>  
> I try to learn python by following the audicity page.
>  
> Now I have the following problem.
>  
> I have two strings a and b 
>  
> Now I have to check if the characters of b are all in a.
> But they do have to be in the same order. 

Perhaps they are looking for something like:

>>> 'abc' in 'someotherabcstring'
True

I suspect that you'll want to figure out how to do that same task with variables now :>)

Take care,
Don


From keithwins at gmail.com  Sun Jan 12 08:02:48 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 12 Jan 2014 02:02:48 -0500
Subject: [Tutor] Tutor Digest, Vol 115, Issue 28
In-Reply-To: <laso3c$qc3$1@ger.gmane.org>
References: <mailman.2095.1379016934.5460.tutor@python.org>
 <CAKSTmRDWd0rZrp-rTUmzzVLyFH1D4ZPb+4G4__o+LAWp0psvYQ@mail.gmail.com>
 <laso3c$qc3$1@ger.gmane.org>
Message-ID: <CAO5ffbbHdpHDZuOcs5z-5T+BQFMTkM+Tq8wAG7b97RJ_UC17sQ@mail.gmail.com>

On Sat, Jan 11, 2014 at 7:37 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> In other words, think about the design of your code don't
> just type randomly.


I prefer the "million monkeys at a million typewriters" approach to
coding...  But then, it's all I've tried...


-- 
Keith

From keithwins at gmail.com  Sun Jan 12 10:04:48 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 12 Jan 2014 04:04:48 -0500
Subject: [Tutor] lambdas, generators, and the like
Message-ID: <CAO5ffbZAWhwYCdqKo==0SDX0y1_E6w8M90N0v111dGzV7G6uyw@mail.gmail.com>

I've got this line:

for k in range(len(tcombo)):
    tcombo_ep.append(list(combinations(tcombo, k+1)))

generating every possible length combination of tcombo. I then test
them, and throw most of them away. I need to do this differently, it
gets way too big (crashes my computer).

I'm going to play some more, but I think I need to test the
combinations as they're generated... and then only add them to a list
(probably better: a set) if they meet a requirement (something like
sum(specific.combination(tcombo) == goal)) AND if they are not already
part of that list (the uniqueness issue is why a set might be better)

I'm partially asking in order to clarify the question in my mind, but
any help will be appreciated. I don't really understand lambda
functions yet, but I can sort of imagine they might work here
somehow... or not.

Thanks!

-- 
Keith

From alan.gauld at btinternet.com  Sun Jan 12 10:19:30 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 12 Jan 2014 09:19:30 +0000
Subject: [Tutor] lambdas, generators, and the like
In-Reply-To: <CAO5ffbZAWhwYCdqKo==0SDX0y1_E6w8M90N0v111dGzV7G6uyw@mail.gmail.com>
References: <CAO5ffbZAWhwYCdqKo==0SDX0y1_E6w8M90N0v111dGzV7G6uyw@mail.gmail.com>
Message-ID: <latmmm$433$1@ger.gmane.org>

On 12/01/14 09:04, Keith Winston wrote:

> I'm partially asking in order to clarify the question in my mind, but
> any help will be appreciated. I don't really understand lambda
> functions yet, but I can sort of imagine they might work here
> somehow... or not.

lambdas are just a shortcut for single expression functions.
You never need them, they just tidy up the code a bit by
avoiding lots of use-once short functions.

I'm not sure they would help a lot in your example. And,
given you don't understand them yet, they would add
complexity.

hth
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From rwobben at hotmail.com  Sun Jan 12 09:12:21 2014
From: rwobben at hotmail.com (Roelof Wobben)
Date: Sun, 12 Jan 2014 08:12:21 +0000
Subject: [Tutor] another better way to do this ?
In-Reply-To: <lasoib$uo9$1@ger.gmane.org>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>,
 <lasoib$uo9$1@ger.gmane.org>
Message-ID: <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>

Hello, 
 
Here is the whole exercise with examples. 
 
# By Sam the Great from forums
# That freaking superhero has been frequenting Udacity
# as his favorite boss battle fight stage. The 'Udacity'
# banner keeps breaking, and money is being wasted on
# repairs. This time, we need you to proceduralize the
# fixing process by building a machine to automatically
# search through debris and return the 'Udacity' banner
# to the company, and be able to similarly fix other goods.
# Write a Python procedure fix_machine to take 2 string inputs
# and returns the 2nd input string as the output if all of its
# characters can be found in the 1st input string and "Give me
# something that's not useless next time." if it's impossible.
# NOTE: # If you are experiencing difficulties taking
        # this problem seriously, please refer back to
        # "Superhero flyby", the prequel, in Problem Set 11.
# TOOLS: # if statement
         # while loop
         # string operations
         # Unit 1 Basics
# BONUS: # 
# 5***** #  If you've graduated from CS101,
#  Gold  #  try solving this in one line.
# Stars! #
def fix_machine(debris, product):
    ### WRITE YOUR CODE HERE ###
### TEST CASES ###
print "Test case 1: ", fix_machine('UdaciousUdacitee', 'Udacity') == "Give me something that's not useless next time."
print "Test case 2: ", fix_machine('buy me dat Unicorn', 'Udacity') == 'Udacity'
print "Test case 3: ", fix_machine('AEIOU and sometimes y... c', 'Udacity') == 'Udacity'
print "Test case 4: ", fix_machine('wsx0-=mttrhix', 't-shirt') == 't-shirt'
 
Roelof

 
> To: tutor at python.org
> From: alan.gauld at btinternet.com
> Date: Sun, 12 Jan 2014 00:45:11 +0000
> Subject: Re: [Tutor] another better way to do this ?
> 
> On 11/01/14 21:24, Roelof Wobben wrote:
> 
> > I have two strings a and b
> >
> > Now I have to check if the characters of b are all in a.
> > But they do have to be in the same order.
> 
> I'm not sure exactly what you mean? Can you give some examples of
> data that pass and that fail the criteria?
> 
> Your algorithm below might meet one definition of the spec but
> its not valid code since it uses return but is not a function.
> 
> > length = len(b)
> > start = 1
> > while start < length :
> >        check = a.find (b[start])
> >        if check == -1 :
> >              return False
> >        start = start + 1
> > return True
> 
> Problems I see are:
> 1) you start testing at b[1] not b[0]
> 2) you don't check if the letters are in the same sequence in a as in b
> 3) you probably could tidy it up using a for loop over b rather than 
> indexing
> 
> > But according to the site this can be solved in a one-liner.
> 
> That depends on the spec.
> And have you covered regular expressions? That is probably one
> way to do a one-liner...
> 
> But just because you can do it in one line doesn't mean you
> should. It's better for code to be readable than short.
> 
> 
> HTH
> -- 
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> 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
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140112/f171e322/attachment.html>

From keithwins at gmail.com  Sun Jan 12 11:03:52 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 12 Jan 2014 05:03:52 -0500
Subject: [Tutor] lambdas, generators, and the like
In-Reply-To: <latmmm$433$1@ger.gmane.org>
References: <CAO5ffbZAWhwYCdqKo==0SDX0y1_E6w8M90N0v111dGzV7G6uyw@mail.gmail.com>
 <latmmm$433$1@ger.gmane.org>
Message-ID: <CAO5ffbYCXBGX0iKbxEmqW2uv59+pJBDnEOExd4qxwNDXVmQvKQ@mail.gmail.com>

On Sun, Jan 12, 2014 at 4:19 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> lambdas are just a shortcut for single expression functions.
> You never need them, they just tidy up the code a bit by
> avoiding lots of use-once short functions.


Thanks, I figured out how to iterate the combinations function. I'll
play with lambda functions some other time. I've been cranking away on
the Project Euler stuff, it's great fun, good Python practice...

-- 
Keith

From alan.gauld at btinternet.com  Sun Jan 12 13:44:20 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 12 Jan 2014 12:44:20 +0000
Subject: [Tutor] another better way to do this ?
In-Reply-To: <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>,
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
Message-ID: <lau2mo$n74$1@ger.gmane.org>

On 12/01/14 08:12, Roelof Wobben wrote:

> # Write a Python procedure fix_machine to take 2 string inputs
> # and returns the 2nd input string as the output if all of its
> # characters can be found in the 1st input string and "Give me
> # something that's not useless next time." if it's impossible.

OK< So there is nothing here about the orders being the same.
That makes it much easier.

> # 5***** #  If you've graduated from CS101,
> #  Gold  #  try solving this in one line.

Its not too hard to do in one line.
I think a filtered list comprehension and the all() function
would be one way.

> print "Test case 1: ", fix_machine('UdaciousUdacitee', 'Udacity') ==
> "Give me something that's not useless next time."
> print "Test case 2: ", fix_machine('buy me dat Unicorn', 'Udacity') ==
> 'Udacity'
> print "Test case 3: ", fix_machine('AEIOU and sometimes y... c',
> 'Udacity') == 'Udacity'
> print "Test case 4: ", fix_machine('wsx0-=mttrhix', 't-shirt') == 't-shirt'

I'd not use the while loop personally, I'd go for a for loop over b
and use the in operation on a. So Something like

for letter in b:
    if letter not in a:
        return   ....
return b

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From __peter__ at web.de  Sun Jan 12 14:21:40 2014
From: __peter__ at web.de (Peter Otten)
Date: Sun, 12 Jan 2014 14:21:40 +0100
Subject: [Tutor] another better way to do this ?
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org> <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
 <lau2mo$n74$1@ger.gmane.org>
Message-ID: <lau4sn$cmm$1@ger.gmane.org>

Alan Gauld wrote:

> On 12/01/14 08:12, Roelof Wobben wrote:
> 
>> # Write a Python procedure fix_machine to take 2 string inputs
>> # and returns the 2nd input string as the output if all of its
>> # characters can be found in the 1st input string and "Give me
>> # something that's not useless next time." if it's impossible.
> 
> OK< So there is nothing here about the orders being the same.
> That makes it much easier.
> 
>> # 5***** #  If you've graduated from CS101,
>> #  Gold  #  try solving this in one line.
> 
> Its not too hard to do in one line.
> I think a filtered list comprehension and the all() function
> would be one way.
> 
>> print "Test case 1: ", fix_machine('UdaciousUdacitee', 'Udacity') ==
>> "Give me something that's not useless next time."
>> print "Test case 2: ", fix_machine('buy me dat Unicorn', 'Udacity') ==
>> 'Udacity'
>> print "Test case 3: ", fix_machine('AEIOU and sometimes y... c',
>> 'Udacity') == 'Udacity'
>> print "Test case 4: ", fix_machine('wsx0-=mttrhix', 't-shirt') ==
>> 't-shirt'
> 
> I'd not use the while loop personally, I'd go for a for loop over b
> and use the in operation on a. So Something like
> 
> for letter in b:
>     if letter not in a:
>         return   ....
> return b

The test cases are not explicit about what to do with multiple occurences of 
the same letter. I'd expect that debris must contain two 't's for 't-shirt' 
to match. So:

print "Test case 5: ", fix_machine('wsx0-=mtrhix', 't-shirt') == "Give me 
something that's not useless next time."

If my assumption is correct a containment test is not sufficient; you need 
to count the characters:

def fix_machine(debris, product):
    return (product
            if all(debris.count(c) >= product.count(c) for c in 
set(product))
            else "Give me something that's not useless next time.")

OP: You'll get bonus points (from me, so they're pointless points, but 
still) if you can solve this (including the fifth apocryphal test case) 
using the collections.Counter class.


From davea at davea.name  Sun Jan 12 15:33:36 2014
From: davea at davea.name (Dave Angel)
Date: Sun, 12 Jan 2014 09:33:36 -0500 (EST)
Subject: [Tutor] lambdas, generators, and the like
References: <CAO5ffbZAWhwYCdqKo==0SDX0y1_E6w8M90N0v111dGzV7G6uyw@mail.gmail.com>
Message-ID: <lau8vm$no0$1@ger.gmane.org>

 Keith Winston <keithwins at gmail.com> Wrote in message:
> I've got this line:
> 
> for k in range(len(tcombo)):
>     tcombo_ep.append(list(combinations(tcombo, k+1)))
> 
> generating every possible length combination of tcombo. I then test
> them, and throw most of them away. I need to do this differently, it
> gets way too big (crashes my computer).
> 
You should learn how to write and use a generator. Anytime you
 find yourself creating a huge list, and only navigating it once, 
 consider writing a generator instead. A generator is any function
 that has a yield in it. You can turn the loop above into a
 one-level generator by

def gen (tcombo):
    for k in range (len (tcombo))
          yield list (combinations (tcombo, k+1))

And depending how you use the nested list, remove the call to list
 () for some real serious space savings. 

(untested)



> any help will be appreciated. I don't really understand lambda
> functions yet, but I can sort of imagine they might work here
> somehow... or not.
> 
A lambda is seldom necessary or useful in simple programs. 
> 


-- 
DaveA nr



----Android NewsGroup Reader----
http://www.piaohong.tk/newsgroup


From davea at davea.name  Sun Jan 12 15:43:45 2014
From: davea at davea.name (Dave Angel)
Date: Sun, 12 Jan 2014 09:43:45 -0500 (EST)
Subject: [Tutor] another better way to do this ?
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>,
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
Message-ID: <lau9in$no0$2@ger.gmane.org>

 Roelof Wobben <rwobben at hotmail.com> Wrote in message:

That documentation says nothing about order.  And the test cases
 specifically contradict it.

so try

if set (b) <= set (a):


-- 
DaveA



----Android NewsGroup Reader----
http://www.piaohong.tk/newsgroup


From eryksun at gmail.com  Sun Jan 12 18:54:32 2014
From: eryksun at gmail.com (eryksun)
Date: Sun, 12 Jan 2014 12:54:32 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <lau4sn$cmm$1@ger.gmane.org>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau2mo$n74$1@ger.gmane.org>
 <lau4sn$cmm$1@ger.gmane.org>
Message-ID: <CACL+1asPrxTZ4Z-E6nnLG9CZvZYDDmNWOY_jsA6vF1SG_U4WEw@mail.gmail.com>

On Sun, Jan 12, 2014 at 8:21 AM, Peter Otten <__peter__ at web.de> wrote:
>
> OP: You'll get bonus points (from me, so they're pointless points, but
> still) if you can solve this (including the fifth apocryphal test case)
> using the collections.Counter class.

Hint:

    >>> print(Counter.__sub__.__doc__)
     Subtract count, but keep only results with positive counts.

            >>> Counter('abbbc') - Counter('bccd')
            Counter({'b': 2, 'a': 1})

    >>> product = Counter('t-shirt')
    >>> product - Counter('wsx0-=mttrhix')
    Counter()
    >>> product - Counter('wsx0-=mtrhix')
    Counter({'t': 1})

`Counter` has multiset methods for the operators +, -, &
(intersection; min count), and | (union; max count). However, it
doesn't implement the `issubset` or `issuperset` methods of `set`, nor
the ordered comparisons (<, >, <=, >=) that depend on them.

From alan.gauld at btinternet.com  Sun Jan 12 19:03:29 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 12 Jan 2014 18:03:29 +0000
Subject: [Tutor] another better way to do this ?
In-Reply-To: <lau9in$no0$2@ger.gmane.org>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>,
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau9in$no0$2@ger.gmane.org>
Message-ID: <lauld5$omv$1@ger.gmane.org>

On 12/01/14 14:43, Dave Angel wrote:

> so try
>
> if set (b) <= set (a):

Ooh, nice! For some reason I've never thought of
applying set to a string before.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From keithwins at gmail.com  Sun Jan 12 19:40:40 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 12 Jan 2014 13:40:40 -0500
Subject: [Tutor] lambdas, generators, and the like
In-Reply-To: <lau8vm$no0$1@ger.gmane.org>
References: <CAO5ffbZAWhwYCdqKo==0SDX0y1_E6w8M90N0v111dGzV7G6uyw@mail.gmail.com>
 <lau8vm$no0$1@ger.gmane.org>
Message-ID: <CAO5ffbbNRmgd0WZFYC3pMNS1+KbYGBz4dJkZR-gDvHvSq0S3_w@mail.gmail.com>

Thanks Dave, that looks like a good idea, I've played a little with
one-line generators (? the things similar to list comprehensions), but
I'm still wrapping my head around how to use them. Meanwhile I'm
reorganizing my code because I now understand better how to use
iterators (i.e. the combinations function), and I'm exploring using
tuples where I can instead of lists... if I followed an earlier
conversation properly, I think garbage collection might happen more
immediately with immutables than mutables, and this program is
crashing either Python or my entire computer every time I run it...
I'm generating a LOT of combinations.

On Sun, Jan 12, 2014 at 9:33 AM, Dave Angel <davea at davea.name> wrote:
>  Keith Winston <keithwins at gmail.com> Wrote in message:
>> I've got this line:
>>
>> for k in range(len(tcombo)):
>>     tcombo_ep.append(list(combinations(tcombo, k+1)))
>>
>> generating every possible length combination of tcombo. I then test
>> them, and throw most of them away. I need to do this differently, it
>> gets way too big (crashes my computer).
>>
> You should learn how to write and use a generator. Anytime you
>  find yourself creating a huge list, and only navigating it once,
>  consider writing a generator instead. A generator is any function
>  that has a yield in it. You can turn the loop above into a
>  one-level generator by
>
> def gen (tcombo):
>     for k in range (len (tcombo))
>           yield list (combinations (tcombo, k+1))
>
> And depending how you use the nested list, remove the call to list
>  () for some real serious space savings.
>
> (untested)
>
>
>
>> any help will be appreciated. I don't really understand lambda
>> functions yet, but I can sort of imagine they might work here
>> somehow... or not.
>>
> A lambda is seldom necessary or useful in simple programs.
>>
>
>
> --
> DaveA nr
>
>
>
> ----Android NewsGroup Reader----
> http://www.piaohong.tk/newsgroup
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Keith

From keithwins at gmail.com  Sun Jan 12 20:22:09 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 12 Jan 2014 14:22:09 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <lau2mo$n74$1@ger.gmane.org>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau2mo$n74$1@ger.gmane.org>
Message-ID: <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>

On Sun, Jan 12, 2014 at 7:44 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> OK< So there is nothing here about the orders being the same.
> That makes it much easier.


There's another approach, I think, that's quite easy if order IS important.

Iterate through the letters of product, find() them initially from the
beginning of debris, and then from the index of the last letter found.
Accounts for multiples in product, & order.

def fix_machine(debris, product):
    index = 0
    success = False
    for letter in product:
        test = debris.find(letter, index)
        if test:
            index = test
        else:   # Failure
            return "Give me something that's not useless next time."
    return product   # Success

I suspect this could be done in one line, without regex, but it would
probably take me a week to figure out... maybe next week ;)

-- 
Keith

From breamoreboy at yahoo.co.uk  Sun Jan 12 20:30:31 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 12 Jan 2014 19:30:31 +0000
Subject: [Tutor] another better way to do this ?
In-Reply-To: <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org> <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
 <lau2mo$n74$1@ger.gmane.org>
 <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>
Message-ID: <lauqgc$g1m$1@ger.gmane.org>

On 12/01/2014 19:22, Keith Winston wrote:
> On Sun, Jan 12, 2014 at 7:44 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>> OK< So there is nothing here about the orders being the same.
>> That makes it much easier.
>
>
> There's another approach, I think, that's quite easy if order IS important.
>
> Iterate through the letters of product, find() them initially from the
> beginning of debris, and then from the index of the last letter found.
> Accounts for multiples in product, & order.
>
> def fix_machine(debris, product):
>      index = 0
>      success = False
>      for letter in product:
>          test = debris.find(letter, index)
>          if test:
>              index = test
>          else:   # Failure
>              return "Give me something that's not useless next time."
>      return product   # Success
>
> I suspect this could be done in one line, without regex, but it would
> probably take me a week to figure out... maybe next week ;)
>

A better idea would be to find out why the above dosn't work correctly, 
I'll leave that in your capable hands :)

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

Mark Lawrence


From keithwins at gmail.com  Sun Jan 12 20:30:54 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 12 Jan 2014 14:30:54 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau2mo$n74$1@ger.gmane.org>
 <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>
Message-ID: <CAO5ffbZxP-VUAYWF0GyOFHohAbAgCpACK24bniPqdV8C2eBZvw@mail.gmail.com>

OOps, I never used the "success" boolean in my code, but forgot to
remove it. Sorry.

From keithwins at gmail.com  Sun Jan 12 20:38:55 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 12 Jan 2014 14:38:55 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau2mo$n74$1@ger.gmane.org>
 <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>
Message-ID: <CAO5ffbZhgQoA+6odvVueRPfaAjNR7DLgkhENnLcyCFxByk6NdA@mail.gmail.com>

On Sun, Jan 12, 2014 at 2:22 PM, Keith Winston <keithwins at gmail.com> wrote:
>         if test:

Sigh.... and this line needs to read (if it's going to do what I said):

        if test != -1:



-- 
Keith

From eryksun at gmail.com  Sun Jan 12 20:47:15 2014
From: eryksun at gmail.com (eryksun)
Date: Sun, 12 Jan 2014 14:47:15 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <CAO5ffbZhgQoA+6odvVueRPfaAjNR7DLgkhENnLcyCFxByk6NdA@mail.gmail.com>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau2mo$n74$1@ger.gmane.org>
 <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>
 <CAO5ffbZhgQoA+6odvVueRPfaAjNR7DLgkhENnLcyCFxByk6NdA@mail.gmail.com>
Message-ID: <CACL+1asveJjtxgJSW67y_uc2fdK=3sno_-SEEwpbqvStrR2DFg@mail.gmail.com>

On Sun, Jan 12, 2014 at 2:38 PM, Keith Winston <keithwins at gmail.com> wrote:
> On Sun, Jan 12, 2014 at 2:22 PM, Keith Winston <keithwins at gmail.com> wrote:
>>         if test:
>
> Sigh.... and this line needs to read (if it's going to do what I said):
>
>         if test != -1:

Consider the case of `product == "letter"`. Do you want to double
match on the 't' found in `debris`? I'm "+1" for finding a solution...

From keithwins at gmail.com  Sun Jan 12 20:50:39 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 12 Jan 2014 14:50:39 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <CAO5ffbZhgQoA+6odvVueRPfaAjNR7DLgkhENnLcyCFxByk6NdA@mail.gmail.com>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau2mo$n74$1@ger.gmane.org>
 <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>
 <CAO5ffbZhgQoA+6odvVueRPfaAjNR7DLgkhENnLcyCFxByk6NdA@mail.gmail.com>
Message-ID: <CAO5ffbZUKK31zEKdDFGqnzvLykp5MXdZLkJj9cw7_4Q4VEVqUA@mail.gmail.com>

On Sun, Jan 12, 2014 at 2:38 PM, Keith Winston <keithwins at gmail.com> wrote:
> Sigh.... and this line needs to read (if it's going to do what I said):

As  Alan pointed out, the examples provided do NOT account for order,
so if one uses my (corrected) algorithm, you get different results
from the examples. Without the fix you get the example results, but
may not realize that it's not accounting for repeats in that case
(which the instructions don't address either). It might be
instructive, if it's not already obvious, to understand why this would
be...

From emile at fenx.com  Sun Jan 12 21:11:26 2014
From: emile at fenx.com (Emile van Sebille)
Date: Sun, 12 Jan 2014 12:11:26 -0800
Subject: [Tutor] another better way to do this ?
In-Reply-To: <lau9in$no0$2@ger.gmane.org>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>,
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau9in$no0$2@ger.gmane.org>
Message-ID: <lausti$96l$1@ger.gmane.org>

On 01/12/2014 06:43 AM, Dave Angel wrote:
>   Roelof Wobben <rwobben at hotmail.com> Wrote in message:
>
> That documentation says nothing about order.  And the test cases
>   specifically contradict it.
>
> so try
>
> if set (b) <= set (a):

or, as the OP specified, if order is relevant,

def test(a,b):
   for ii in a:
     if ii not in b: a=a.replace(ii,"")
   return b in a

Emile






From __peter__ at web.de  Sun Jan 12 21:21:51 2014
From: __peter__ at web.de (Peter Otten)
Date: Sun, 12 Jan 2014 21:21:51 +0100
Subject: [Tutor] another better way to do this ?
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org> <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
 <lau9in$no0$2@ger.gmane.org> <lausti$96l$1@ger.gmane.org>
Message-ID: <lautgh$ff4$1@ger.gmane.org>

Emile van Sebille wrote:

> On 01/12/2014 06:43 AM, Dave Angel wrote:
>>   Roelof Wobben <rwobben at hotmail.com> Wrote in message:
>>
>> That documentation says nothing about order.  And the test cases
>>   specifically contradict it.
>>
>> so try
>>
>> if set (b) <= set (a):
> 
> or, as the OP specified, if order is relevant,
> 
> def test(a,b):
>    for ii in a:
>      if ii not in b: a=a.replace(ii,"")
>    return b in a

>>> def test(a,b):
...    for ii in a:
...      if ii not in b: a=a.replace(ii,"")
...    return b in a
... 
>>> test("axbxc", "abc")
True
>>> test("abbxc", "abc")
False

Is the second result desired?


From emile at fenx.com  Sun Jan 12 21:53:23 2014
From: emile at fenx.com (Emile van Sebille)
Date: Sun, 12 Jan 2014 12:53:23 -0800
Subject: [Tutor] another better way to do this ?
In-Reply-To: <lautgh$ff4$1@ger.gmane.org>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org> <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
 <lau9in$no0$2@ger.gmane.org> <lausti$96l$1@ger.gmane.org>
 <lautgh$ff4$1@ger.gmane.org>
Message-ID: <lauvc6$3pk$1@ger.gmane.org>

On 01/12/2014 12:21 PM, Peter Otten wrote:

>>>> test("axbxc", "abc")
> True
>>>> test("abbxc", "abc")
> False
>
> Is the second result desired?

No -- the second should match -- you found a test case I didn't...

def test(a,b):
   for ii in a:
     if ii not in b: a=a.replace(ii,"")
     while ii+ii in a: a=a.replace(ii+ii,ii)
   return b in a

Show me another.  :)

Emile





From __peter__ at web.de  Sun Jan 12 22:17:20 2014
From: __peter__ at web.de (Peter Otten)
Date: Sun, 12 Jan 2014 22:17:20 +0100
Subject: [Tutor] another better way to do this ?
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org> <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
 <lau9in$no0$2@ger.gmane.org> <lausti$96l$1@ger.gmane.org>
 <lautgh$ff4$1@ger.gmane.org> <lauvc6$3pk$1@ger.gmane.org>
Message-ID: <lav0oi$ft2$1@ger.gmane.org>

Emile van Sebille wrote:

> On 01/12/2014 12:21 PM, Peter Otten wrote:
> 
>>>>> test("axbxc", "abc")
>> True
>>>>> test("abbxc", "abc")
>> False
>>
>> Is the second result desired?
> 
> No -- the second should match -- you found a test case I didn't...
> 
> def test(a,b):
>    for ii in a:
>      if ii not in b: a=a.replace(ii,"")
>      while ii+ii in a: a=a.replace(ii+ii,ii)
>    return b in a
> 
> Show me another.  :)

>>> def test(a,b):
...    for ii in a:
...      if ii not in b: a=a.replace(ii,"")
...      while ii+ii in a: a=a.replace(ii+ii,ii)
...    return b in a
... 
>>> test("abac", "abc")
False



From keithwins at gmail.com  Sun Jan 12 22:43:40 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 12 Jan 2014 16:43:40 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau2mo$n74$1@ger.gmane.org>
 <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>
Message-ID: <CAO5ffbYOBfzFJOgnp-N4=vTFc378x7+-x+iiT0SN2xgdmpMCvg@mail.gmail.com>

On Sun, Jan 12, 2014 at 2:22 PM, Keith Winston <keithwins at gmail.com> wrote:
> There's another approach, I think, that's quite easy if order IS important.

Alas, there's one further problem with my script, relating to testing
multiple sequential letters in product... but I'm not going to say
more, I'll leave it as a problem for the OP. It's an easy fix once you
understand the issue.

-- 
Keith

From keithwins at gmail.com  Mon Jan 13 00:12:41 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 12 Jan 2014 18:12:41 -0500
Subject: [Tutor] Euler Spoiler
Message-ID: <CAO5ffbYjxh9AcPhTBGUrX5_fxayyikCvP3fG2X-XDxNP4ErppQ@mail.gmail.com>

I'm working through some of the Project Euler problems, and the
following might spoil one of the problems, so perhaps you don't want
to read further...


The problem relates to finding all possible combinations of coins that
equal a given total. I'm basically brute-forcing it, which is probably
not the way to go, but has already taught me a good bit about sets,
tuples, and iterators, so... so far so good.

However, after all the refactoring I can think of, I can't get it past
a 3-coin list without it bogging down.

I'm sure there are wholly different approaches, feel free to hint at
them, but my real question is: is there any further fine-tuning of my
approach (or any outright problems with it) that would be instructive?
Thanks!

Also: I think it might have worked better with lists that tuples,
though I don't really understand why, unless I misunderstand speed or
memory management issues (or something else).

from itertools import combinations

coins = [100, 50, 20]  # should include 1, 2, 5, 10 (plus one 200 combo)
ans = set()
goal = 200
tcombo = ()

# Iterate over all possible length combinations of coins
for i in range(len(coins)):
    print(i)
    # For each unique combo of coins, and...
    for combo in combinations(coins, i+1):
        tcombo = ()
        # For each coin in that combo...
        for coin in combo:
            # create a new tuple of as many of those coins as
            # it would take to reach the goal
            tcombo = tcombo + (coin,) * int(goal/coin)
            # with this new extended list, generate all possible
length combinations
            for k in range(len(tcombo)):
                for c in combinations(tcombo, k + 1):
                    if sum(c) == goal:
                        ans = ans | {c}

print(ans)


-- 
Keith

From wprins at gmail.com  Mon Jan 13 02:02:13 2014
From: wprins at gmail.com (Walter Prins)
Date: Mon, 13 Jan 2014 01:02:13 +0000
Subject: [Tutor] Euler Spoiler
In-Reply-To: <CAO5ffbYjxh9AcPhTBGUrX5_fxayyikCvP3fG2X-XDxNP4ErppQ@mail.gmail.com>
References: <CAO5ffbYjxh9AcPhTBGUrX5_fxayyikCvP3fG2X-XDxNP4ErppQ@mail.gmail.com>
Message-ID: <CANLXbfAyyrhpwCAej3L=qszK-NCCnd5vQfWf+2Xk8gFZqq=5ig@mail.gmail.com>

Hi Keith,

On 12 January 2014 23:12, Keith Winston <keithwins at gmail.com> wrote:

> I'm working through some of the Project Euler problems, and the
> following might spoil one of the problems, so perhaps you don't want
> to read further...
>
>
> The problem relates to finding all possible combinations of coins that
> equal a given total. I'm basically brute-forcing it, which is probably
> not the way to go, but has already taught me a good bit about sets,
> tuples, and iterators, so... so far so good.
>
> However, after all the refactoring I can think of, I can't get it past
> a 3-coin list without it bogging down.
>

Sorry I haven't got time to look at your attempt closely (nearly 1am here),
but try/have a look at this:

from itertools import chain, combinations

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    #Taken from: http://docs.python.org/2/library/itertools.html
    #(It doesn't strictly operate on or generate sets as can be seen.)
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

coins = [100, 50, 20, 20, 10, 10, 10]
goal = 200

solutions = set(list(s for s in powerset(coins) if sum(s) == goal))
print solutions
# outputs: set([(100, 50, 20, 20, 10), (100, 50, 20, 10, 10, 10)])



Walter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140113/1ad5aeed/attachment.html>

From dyoo at hashcollision.org  Mon Jan 13 02:24:50 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sun, 12 Jan 2014 17:24:50 -0800
Subject: [Tutor] Euler Spoiler
In-Reply-To: <CAO5ffbYjxh9AcPhTBGUrX5_fxayyikCvP3fG2X-XDxNP4ErppQ@mail.gmail.com>
References: <CAO5ffbYjxh9AcPhTBGUrX5_fxayyikCvP3fG2X-XDxNP4ErppQ@mail.gmail.com>
Message-ID: <CAGZAPF64VEtGm5J3cEJCKC90y0yMEXbEecp==jakEZVwfO825w@mail.gmail.com>

This sounds very much like a problem that demands trying to break the
problems down into subproblems, and then applying a
"dynamic-programming approach" to make it fairly easy to get an
efficient solution.  Such problems that are amendable to this approach
have a "substructure" to them so that the main problem breaks down
into smaller versions of the same problem.


As an example, Problem 15 on Lattice paths is a good one:

   http://projecteuler.net/problem=15

Here, the problem is asking: count how many paths there are in the n*n
grid.  A sub-problem of this is: count how many paths there are in the
(n-1)*n graph, and count how many paths there are in the N*(n-1) grid.
 Why are those particular subproblems interesting?  Because if you
have the answer for the (n-1)*n and the n*(n-1), then you add the
results of those two together, and you get the answer for the original
n*n case!


Another example of a dynamic programming situation is in Problem 18,

    http://projecteuler.net/problem=18

where we can decompose the problem of trying to find the path that
maximizes the sum from the triangle as a whole to the sub-triangles on
the left and right hand sides.


In your problem statement, you're trying to answer the question:

    Given some goal g, find all the ways to break change.

A subproblem of this is:

    Given some goal (g - x) for each x in the denominations, find all
the ways to break change.

That is, a trick to solving the problem is to treat 'goal' as a
variable, part of the problem statement that can be changed.


Are you familiar with the dynamic programming approach?  I'm sure
folks here would be happy to talk about it more and show concrete
examples; it's a very powerful tool.

From davea at davea.name  Mon Jan 13 02:35:18 2014
From: davea at davea.name (Dave Angel)
Date: Sun, 12 Jan 2014 20:35:18 -0500 (EST)
Subject: [Tutor] Euler Spoiler
References: <CAO5ffbYjxh9AcPhTBGUrX5_fxayyikCvP3fG2X-XDxNP4ErppQ@mail.gmail.com>
Message-ID: <lavfoe$l5$1@ger.gmane.org>

 Keith Winston <keithwins at gmail.com> Wrote in message:
> I'm working through some of the Project Euler problems, and the
> following might spoil one of the problems, so perhaps you don't want
> to read further...
> 
> 
> The problem relates to finding all possible combinations of coins that
> equal a given total. I'm basically brute-forcing it, which is probably
> not the way to go, but has already taught me a good bit about sets,
> tuples, and iterators, so... so far so good.
> 
> However, after all the refactoring I can think of, I can't get it past
> a 3-coin list without it bogging down.

Care to define "bogging down"?  If you mean it gets REALLY slow
 then I'm not surprised.  Do you have any idea how many
 combinations there are for even a moderate sized list of
 coins?

For the call  combinations(tcombo, k + 1) with k =99 and tcombo of
 size 200, the number of iterations has 59 digits.  With a really
 fast computer you might scratch the surface in a trillion
 trillion trillion years.

One way to improve on that enormously would be to scrap tcombo and
 call itertool.combinations_with_replacement. But I think the
 notion of generating all combinations and then selecting is
 doomed to failure for all but the smallest problems.

Incidentally I think you have way too many nested loops. Even if
 brute force were going to work,  you'd do it with
 itertool.combinations_with_replacement(coins without doing combo
 or tcombo. 


-- 
DaveA



----Android NewsGroup Reader----
http://www.piaohong.tk/newsgroup


From keithwins at gmail.com  Mon Jan 13 03:24:43 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 12 Jan 2014 21:24:43 -0500
Subject: [Tutor] Euler Spoiler
In-Reply-To: <lavfoe$l5$1@ger.gmane.org>
References: <CAO5ffbYjxh9AcPhTBGUrX5_fxayyikCvP3fG2X-XDxNP4ErppQ@mail.gmail.com>
 <lavfoe$l5$1@ger.gmane.org>
Message-ID: <CAO5ffbbg24qN0LNLgUXT3JoWXdgDd0jQL1584avud-K+GtRK0Q@mail.gmail.com>

Thanks everyone, things to chew on. I'll look at the other itertools
functions mentioned. I did solve Proj. Euler 15 & 18 (and it's
corresponding 67), one more elegantly than the other, and I have given
some thought to how to break this one down, but haven't figured it out
yet. I think I might not be willing to wait a trillion years. I think
I'm going to stop development on this approach, both 1) because I
don't think it's going to work, and 2) because I might have learned
most of what I can from it, re: Python skills.

I am quite interested in the dynamic programming approach, which I
understand my approach to PE 18 was consistent with, but which I don't
yet understand how to apply more broadly or consistently. I'll do some
reading on it.

From dyoo at hashcollision.org  Mon Jan 13 06:56:09 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sun, 12 Jan 2014 21:56:09 -0800
Subject: [Tutor] Euler Spoiler
In-Reply-To: <CAO5ffbbg24qN0LNLgUXT3JoWXdgDd0jQL1584avud-K+GtRK0Q@mail.gmail.com>
References: <CAO5ffbYjxh9AcPhTBGUrX5_fxayyikCvP3fG2X-XDxNP4ErppQ@mail.gmail.com>
 <lavfoe$l5$1@ger.gmane.org>
 <CAO5ffbbg24qN0LNLgUXT3JoWXdgDd0jQL1584avud-K+GtRK0Q@mail.gmail.com>
Message-ID: <CAGZAPF4D=Ar7+f8xUrCsYLZ0S3901KgEvHv7bscLFDcRGGt-0A@mail.gmail.com>

To be concrete, I think you're looking at Problem 31, right?

    http://projecteuler.net/problem=31

in which case, we have a few choices for denomination:

    1p, 2p, 5p, 10p, 20p, 50p, 100p, 200p

and we're trying to _count_ how many ways to make 200p.



Here's a sketch of how I'd attack this by considering a DP-style
approach.  If you want to avoid any spoilers, please skip this
message.

Otherwise, I'll try to be as transparent as to my thought process as I can.

-----------------------------------------------------------------------

We first want to "name and conquer".

Let C(k) be the number of ways to make change for 'k' pence.

Why C(k)?  Because I think C(200) is what we're looking for.  I'm
making 'k' be the parameter here because I think an approach that
tries to figure out C, where n ranges from [0-200], should do the
trick.


Note: for now, let's assume that C does not remember _how_ we're
making the change.  It should only remember the number of ways to do
so.



What are some values for C?  Let us try to reason what C must be for
low values of 'k'.

------

C(0) = 1.  There's one way to make change for zero pence, namely the
empty case.  It might be important to argue this edge case, so that's
why I'm considering it.

------

C(1) = 1.  We know we can do this one trivially.

    1p

------

C(2) = 2.  We can either do it as:

    1p + 1p, or
    2p

------

C(3) = 2.  We can do it as:

    2p + 1p, or
    1p + 1p + 1p.



Note: we don't want to treat:

    1p + 2p

as another possibility!

Why not?  Because that would be a duplicate of

    2p + 1p

which we already counted for already.

Believe it or not, this observation is important, because we'll find
in a few moments that it forces us to reconsider an amendment to our
approach.

-----------------------------------------------


One observation so far: it looks like we can construct more of C by
looking at previous elements of C.  That would mean we just run
through constructing C "bottom-up", from k=1 through 200.  If that's
the case, then we're golden.  We can just keep the intermediate values
of C as an array of ints.

Easy.

Or not.  :P  Let's see what happens.


------

C(4) = ...?

This is starting not to be so obvious.

Let's try to reason it out.  From our observation, let's see if we can
just take previous elements that we computed for C and just sum it up
in some nice way.

If we're trying to make change for four pence, then...

1.  If there's a change-making sequence that starts of as:

    "2p + ...",

for example, the "..." would stand for ways of making change for the
remainder 4p - 2p == 2p.

Looking back at how we computed C(2), we could make C(2) out of:

    1p + 1p, or
    2p

So if we just put "2p" in front of those, that gives us:

    2p + 1p + 1p, or
    2p + 2p.

Good!


2.  If there's a change-making sequence that starts off as "1p + ...",
for example, the "..." would stand for the ways of making change for
the remainder 4p - 1p == 3p.

Looking back at how we computed C(3), we know that it was constructed out of:

    2p + 1p, or
    1p + 1p + 1p.

So maybe we can just put 1p in front of those!

    1p + ... <ways of making C(3)>

    ==>

    1p + 2p + 1p, or
    1p + 1p + 1p + 1p.


... Oh!  But wait, we don't want to count:

    1p + 2p + 1p

because we already did that, essentially, when we did

    2p + 1p + 1p

In fact, we ran into this issue earlier on when we were trying to
figure out C(3).


So C(4) is 3, because we can make it out of:

    2p + 1p + 1p, or
    2p + 2p, or
    1p + 1p + 1p + 1p.

---

Huh.  That wasn't as simple as just adding up previous values for C.  Nuts.


Let's think about this a bit.  Earlier, we were hoping we could just
naively look at C for previous values of k, and just add them up.  But
we want to make sure we DON'T over-count ways of making the change.


The difficulty that we're running across is due to the structure of C:
it doesn't let us know if we're counting a change-making that already
takes into consideration something we already counted.

What to do?

Maybe our earlier approach, to not remember how exactly we're making
the change, can be amended.

One approach might be to change the return type of C.  Rather than
have it keep track of just the number of ways of counting change, we
might instead hold onto a description of the change sums themselves.
This should work!  But it would mean that we have to hold a list of
list of denominations.  And we'd have to do an additional
duplication-filtering step.  But we know we can do it this way, if we
really needed to.



But there is another approach.  I will sketch this approach out
because I'm pretty sure it's the one the problem writers intended.

Let's look again at that troublesome change-making that's causing us grief:

    1p + 2p + 1p

We don't want this because it's a duplicate of:

    2p + 1p + 1p

Well, what's different about it?  The numbers are in a different
order.  The case we don't care particularly for, 1p + 2p + 1p, have
numbers in a "mixed up" order.

Crazy idea: how about we force it so we're only consider
"nonincreasing" configurations?

Maybe we can amend things so we don't consider 1p + 2p + 1p.  What
made us consider this in the first place?  Well, we were trying to
figure out C(4).  We took 1p out, and then started looking at how we
figured out C(3).  But we know we don't want to look at 2p+1p here: we
took 1p out, so anything that uses anything bigger than 1p would have
already been counted earlier!


So how about we add an additional parameter to C?  Name and conquer!


We revise the type of C so it takes in two arguments.  Let C(k, d) be
the number of ways of making change for k pence, when d is the highest
denomination to be used in making that change.


For example, consider C(k, 1).  If we're only allowed to use one pence
to make change, then there's only one way to make change for k pence:
by using only single pences.

    C(k, 1) = 1               for all k.


How does adding this 'd' parameter help us?  Well, if we're trying to
figure out all the ways of making change for 4 pence, and we start off
asking out to make:

    1p + ...,

we can just use the answer from C(3, 1).

That fixes the problem of considering 1p + 2p + 1p: we eliminate that
case by filtering it out via using appropriately small denominations
'd' for the remainder.


-------

More generally, how do we compute C(k, d)?

We can sum up

   C(k - c, c)

for all candidate coins c that are smaller than or equal to d.

------

Let's look at how that'd work for C(4, 2), the case that we were
having difficulty before.  We have two candidate coins we get to use
here, 1p, and 2p.

Let's say we start off using 1p.  Then we want:

        C(4-1, 1)
    -> C(3, 1)

which asks: how many ways to make change out for 3p, when we're only
allowed to us single pence.  And we know this already.  C(3, 1) = 1,
due to reasoning out what C(k, 1) means for any k.


Ok, what if we start with 2p?  Then we want:

        C(4-2, 2)
    -> C(2, 2)

How many ways can we make change for 2 pence, if we're allowed to use
as high a denomination as 2p?  We know this already as well: we did
this when working out the original C(2), when we weren't thinking of
the second argument 'd'.  C(2) = 2.


That is, we now know that:

    C(4, 2) = C(3, 1) + C(2, 2)
               = 1 + 2
               = 3
-----


And that's really a way we can nail this problem.  Once you understand
what's happening, the code to compute the solution to Euler Problem 31
ends up being only a few lines long!  Not only that, but the concepts
the code uses is nothing more complicated than a 2d array and a few
loops.  No power sets, no itertools, just some basic fundamental
types.

It's astonishingly "simple-looking" code, even if the reasons why the
code works is non-obvious.



Apologies for the length of the post.  But hopefully it helps a little.

From rwobben at hotmail.com  Mon Jan 13 07:14:08 2014
From: rwobben at hotmail.com (Roelof Wobben)
Date: Mon, 13 Jan 2014 06:14:08 +0000
Subject: [Tutor] another better way to do this ?
In-Reply-To: <CAO5ffbYOBfzFJOgnp-N4=vTFc378x7+-x+iiT0SN2xgdmpMCvg@mail.gmail.com>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>,
 <lasoib$uo9$1@ger.gmane.org>, <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
 <lau2mo$n74$1@ger.gmane.org>,
 <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>,
 <CAO5ffbYOBfzFJOgnp-N4=vTFc378x7+-x+iiT0SN2xgdmpMCvg@mail.gmail.com>
Message-ID: <DUB121-W293D81645F406374A4A612AEBC0@phx.gbl>

I have read all comments and im a little bit confused.
About which script are we talkimng about. I have seen a lot.
 
Roelof
 
> From: keithwins at gmail.com
> Date: Sun, 12 Jan 2014 16:43:40 -0500
> CC: tutor at python.org
> Subject: Re: [Tutor] another better way to do this ?
> 
> On Sun, Jan 12, 2014 at 2:22 PM, Keith Winston <keithwins at gmail.com> wrote:
> > There's another approach, I think, that's quite easy if order IS important.
> 
> Alas, there's one further problem with my script, relating to testing
> multiple sequential letters in product... but I'm not going to say
> more, I'll leave it as a problem for the OP. It's an easy fix once you
> understand the issue.
> 
> -- 
> Keith
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140113/67572b01/attachment.html>

From keithwins at gmail.com  Mon Jan 13 18:51:02 2014
From: keithwins at gmail.com (Keith Winston)
Date: Mon, 13 Jan 2014 12:51:02 -0500
Subject: [Tutor] Euler Spoiler
In-Reply-To: <CAGZAPF4D=Ar7+f8xUrCsYLZ0S3901KgEvHv7bscLFDcRGGt-0A@mail.gmail.com>
References: <CAO5ffbYjxh9AcPhTBGUrX5_fxayyikCvP3fG2X-XDxNP4ErppQ@mail.gmail.com>
 <lavfoe$l5$1@ger.gmane.org>
 <CAO5ffbbg24qN0LNLgUXT3JoWXdgDd0jQL1584avud-K+GtRK0Q@mail.gmail.com>
 <CAGZAPF4D=Ar7+f8xUrCsYLZ0S3901KgEvHv7bscLFDcRGGt-0A@mail.gmail.com>
Message-ID: <CAO5ffbZXNyev8fiaLv51s3=rh_yd2sYjRyLXMYxfQdg6-d9=9A@mail.gmail.com>

Danny, thanks for that exposition. I don't have time to absorb it
yet,though I will attempt to soon, but I wanted to thank you for your
effort in the meantime.

Keith

From keithwins at gmail.com  Mon Jan 13 18:56:45 2014
From: keithwins at gmail.com (Keith Winston)
Date: Mon, 13 Jan 2014 12:56:45 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <DUB121-W293D81645F406374A4A612AEBC0@phx.gbl>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau2mo$n74$1@ger.gmane.org>
 <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>
 <CAO5ffbYOBfzFJOgnp-N4=vTFc378x7+-x+iiT0SN2xgdmpMCvg@mail.gmail.com>
 <DUB121-W293D81645F406374A4A612AEBC0@phx.gbl>
Message-ID: <CAO5ffbbaYWXZrXLbu5PV4pn9-2ncnNvoxEAjPnhWeDZmarACaA@mail.gmail.com>

On Mon, Jan 13, 2014 at 1:14 AM, Roelof Wobben <rwobben at hotmail.com> wrote:
> I have read all comments and im a little bit confused.
> About which script are we talkimng about. I have seen a lot.


I am talking about the script/approach I posted. Others have posted
other scripts. Hopefully you have the capacity, with whatever approach
to reading email you have, to go back and look over messages?

There is some confusion because your original message specified that
order was important, though the examples you gave did not indicate
that (in fact, contradicted it). Also, there was never anything
specified about repeated letters: what would be the result of
fix_machine("letr", "letter") (not to be confused with
fix_machine("letter", "letr"), which would definitely be "letr").

-- 
Keith

From __peter__ at web.de  Mon Jan 13 19:22:08 2014
From: __peter__ at web.de (Peter Otten)
Date: Mon, 13 Jan 2014 19:22:08 +0100
Subject: [Tutor] another better way to do this ?
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org> <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
 <lau9in$no0$2@ger.gmane.org> <lausti$96l$1@ger.gmane.org>
 <lautgh$ff4$1@ger.gmane.org> <lauvc6$3pk$1@ger.gmane.org>
 <lav0oi$ft2$1@ger.gmane.org>
Message-ID: <lb1aru$k8h$1@ger.gmane.org>

Peter Otten wrote:

> Emile van Sebille wrote:
> 
>> On 01/12/2014 12:21 PM, Peter Otten wrote:
>> 
>>>>>> test("axbxc", "abc")
>>> True
>>>>>> test("abbxc", "abc")
>>> False
>>>
>>> Is the second result desired?
>> 
>> No -- the second should match -- you found a test case I didn't...
>> 
>> def test(a,b):
>>    for ii in a:
>>      if ii not in b: a=a.replace(ii,"")
>>      while ii+ii in a: a=a.replace(ii+ii,ii)
>>    return b in a
>> 
>> Show me another.  :)
> 
>>>> def test(a,b):
> ...    for ii in a:
> ...      if ii not in b: a=a.replace(ii,"")
> ...      while ii+ii in a: a=a.replace(ii+ii,ii)
> ...    return b in a
> ...
>>>> test("abac", "abc")
> False

In the mean time here is my candidate:

def test(a, b):
    a = iter(a)
    return all(c in a for c in b)



From keithwins at gmail.com  Mon Jan 13 19:31:39 2014
From: keithwins at gmail.com (Keith Winston)
Date: Mon, 13 Jan 2014 13:31:39 -0500
Subject: [Tutor] Euler Spoiler
In-Reply-To: <CAO5ffbZXNyev8fiaLv51s3=rh_yd2sYjRyLXMYxfQdg6-d9=9A@mail.gmail.com>
References: <CAO5ffbYjxh9AcPhTBGUrX5_fxayyikCvP3fG2X-XDxNP4ErppQ@mail.gmail.com>
 <lavfoe$l5$1@ger.gmane.org>
 <CAO5ffbbg24qN0LNLgUXT3JoWXdgDd0jQL1584avud-K+GtRK0Q@mail.gmail.com>
 <CAGZAPF4D=Ar7+f8xUrCsYLZ0S3901KgEvHv7bscLFDcRGGt-0A@mail.gmail.com>
 <CAO5ffbZXNyev8fiaLv51s3=rh_yd2sYjRyLXMYxfQdg6-d9=9A@mail.gmail.com>
Message-ID: <CAO5ffbb52osMOFe69WGg25_ZD1d8_28rbeyM+CEr+iPmv_=53A@mail.gmail.com>

Ah, I got through it. Yes, I started down this path, but didn't dot
the i's. Thanks. I'm going to do some more reading on dynamic
programming...

Keith

On Mon, Jan 13, 2014 at 12:51 PM, Keith Winston <keithwins at gmail.com> wrote:
> Danny, thanks for that exposition. I don't have time to absorb it
> yet,though I will attempt to soon, but I wanted to thank you for your
> effort in the meantime.
>
> Keith



-- 
Keith

From keithwins at gmail.com  Mon Jan 13 19:36:46 2014
From: keithwins at gmail.com (Keith Winston)
Date: Mon, 13 Jan 2014 13:36:46 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <lb1aru$k8h$1@ger.gmane.org>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau9in$no0$2@ger.gmane.org>
 <lausti$96l$1@ger.gmane.org> <lautgh$ff4$1@ger.gmane.org>
 <lauvc6$3pk$1@ger.gmane.org>
 <lav0oi$ft2$1@ger.gmane.org> <lb1aru$k8h$1@ger.gmane.org>
Message-ID: <CAO5ffbb9oaWr8j1jdDWcAnZYER4NSqv8+M=Z-iwooT9K2vaZPg@mail.gmail.com>

Yikes, Peter, that's scary. Wow.

On Mon, Jan 13, 2014 at 1:22 PM, Peter Otten <__peter__ at web.de> wrote:
> Peter Otten wrote:
>
>> Emile van Sebille wrote:
>>
>>> On 01/12/2014 12:21 PM, Peter Otten wrote:
>>>
>>>>>>> test("axbxc", "abc")
>>>> True
>>>>>>> test("abbxc", "abc")
>>>> False
>>>>
>>>> Is the second result desired?
>>>
>>> No -- the second should match -- you found a test case I didn't...
>>>
>>> def test(a,b):
>>>    for ii in a:
>>>      if ii not in b: a=a.replace(ii,"")
>>>      while ii+ii in a: a=a.replace(ii+ii,ii)
>>>    return b in a
>>>
>>> Show me another.  :)
>>
>>>>> def test(a,b):
>> ...    for ii in a:
>> ...      if ii not in b: a=a.replace(ii,"")
>> ...      while ii+ii in a: a=a.replace(ii+ii,ii)
>> ...    return b in a
>> ...
>>>>> test("abac", "abc")
>> False
>
> In the mean time here is my candidate:
>
> def test(a, b):
>     a = iter(a)
>     return all(c in a for c in b)
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Keith

From rwobben at hotmail.com  Mon Jan 13 19:06:32 2014
From: rwobben at hotmail.com (Roelof Wobben)
Date: Mon, 13 Jan 2014 18:06:32 +0000
Subject: [Tutor] another better way to do this ?
In-Reply-To: <CAO5ffbbaYWXZrXLbu5PV4pn9-2ncnNvoxEAjPnhWeDZmarACaA@mail.gmail.com>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>,<DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
 <lau2mo$n74$1@ger.gmane.org>,
 <CAO5ffbZB089XZA_eeZBzV5=AN2CFjYWB7ReK7b=Cq=bYT2CX-w@mail.gmail.com>,
 <CAO5ffbYOBfzFJOgnp-N4=vTFc378x7+-x+iiT0SN2xgdmpMCvg@mail.gmail.com>
 <DUB121-W293D81645F406374A4A612AEBC0@phx.gbl>,
 <CAO5ffbbaYWXZrXLbu5PV4pn9-2ncnNvoxEAjPnhWeDZmarACaA@mail.gmail.com>
Message-ID: <DUB121-W322CF597A598E61650AD2BAEBC0@phx.gbl>



> From: keithwins at gmail.com
> Date: Mon, 13 Jan 2014 12:56:45 -0500
> Subject: Re: [Tutor] another better way to do this ?
> To: rwobben at hotmail.com
> CC: tutor at python.org
> 
> On Mon, Jan 13, 2014 at 1:14 AM, Roelof Wobben <rwobben at hotmail.com> wrote:
> > I have read all comments and im a little bit confused.
> > About which script are we talkimng about. I have seen a lot.
> 
> 
> I am talking about the script/approach I posted. Others have posted
> other scripts. Hopefully you have the capacity, with whatever approach
> to reading email you have, to go back and look over messages?
> 
> There is some confusion because your original message specified that
> order was important, though the examples you gave did not indicate
> that (in fact, contradicted it). Also, there was never anything
> specified about repeated letters: what would be the result of
> fix_machine("letr", "letter") (not to be confused with
> fix_machine("letter", "letr"), which would definitely be "letr").
> 
> -- 
> Keith

Oke, 

I think you mean this script :

def fix_machine(debris, product):
    index = 0
    for letter in product:
        test = debris.find(letter, index)
        if test!= -1:
            index = test
        else:   # Failure
            return "Give me something that's not useless next time."
    return product   # Success
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140113/00e40710/attachment.html>

From stareq13 at yahoo.com  Mon Jan 13 18:30:01 2014
From: stareq13 at yahoo.com (S Tareq)
Date: Mon, 13 Jan 2014 17:30:01 +0000 (GMT)
Subject: [Tutor] how to use 2to3
Message-ID: <1389634201.66114.YahooMailNeo@web133101.mail.ir2.yahoo.com>

can you please help me how to use 2to3 on 3.3. i went to the web site follow instraction and it did not work.?


# Import statements
import random
import datetime
#Arrays to store the definitions and keywords read from the file
keywords=[];
definition=[];
correctAnswer=[];
#Counter for the wrong Answer and counter of number of definition in
correctAnswerCounter=0?
wrongAnswer=0;
counter=0;
# Taking User input for accepting the file name to be read
filename= raw_input("Enter the File Name with extension")
#Reading the file from start to the end
for line in open(filename,'r').readlines():
? ? if(counter%2==0):
? ? ? ? keywords.append(line);
? ? ? ? counter=counter+1;
? ? ? ? correctAnswer.append(0)
? ? else:
? ? ? ? definition.append(line);
? ? ? ? keys=[];
? ? ? ? keys=line.split(" ");
? ? ? ? counter=counter+1;
# Running two while loops to make the pattern recursive
while True:
# Starting the time for quiz and also, creating variables to make sure that same sequences and answers are not repeated
? ? a = datetime.datetime.now().replace(microsecond=0)
? ? prevWord=0
? ? prevSeq=0
? ? # While loop to run the code till each answer is correctly answered
? ? while correctAnswer.count(2)!=(counter/2):
? ? ? ? #While loop to generate an different random number from one the generated previously
? ? ? ? while True: ? ? ? ?
? ? ? ? ? ? word=random.randint(0,(counter/2)-1)
? ? ? ? ? ? if(correctAnswer[word]!=2):
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? if(prevWord==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? # Displaying the new keyword each time.
? ? ? ? print "Please Select the number which is the correct definition of the word:" ,keywords[word]
? ? ? ? #Generating an new sequence each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? sequences =random.randint(0,2)
? ? ? ? ? ? if(prevSeq==sequences):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswer=random.randint(0,len(correctAnswer)-1)
? ? ? ? ? ? if(incorrectAnswer==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else :
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer ?each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswerSecond=random.randint(0,len(correctAnswer)-1);
? ? ? ? ? ? if (incorrectAnswer==incorrectAnswerSecond):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? if(incorrectAnswerSecond==word):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? # Displaying the options to the user based on the sequence number generated
? ? ? ? if (sequences==0):
? ? ? ? ? ? print "1.",definition[word]
? ? ? ? ? ? print "2.",definition[incorrectAnswer]
? ? ? ? ? ? print "3.",definition[incorrectAnswerSecond]
? ? ? ? elif (sequences==1):
? ? ? ? ? ? print "1.",definition[incorrectAnswer]
? ? ? ? ? ? print "2.",definition[incorrectAnswerSecond]
? ? ? ? ? ? print "3.",definition[word]
? ? ? ? elif (sequences==2):
? ? ? ? ? ? print "1.",definition[incorrectAnswerSecond]
? ? ? ? ? ? print "2.",definition[word]
? ? ? ? ? ? print "3.",definition[incorrectAnswer]
? ? ? ? #Taking the answer from user
? ? ? ? answer = raw_input("Enter the Correct Number between 1 to 3")
? ? ? ? # Assign the seq and word to preseq and word
? ? ? ? prevSeq=sequences
? ? ? ? prevWord=word
? ? ? ? #Checking the answer if they are corret.
? ? ? ? if(0 == sequences):
? ? ? ? ? ? if(answer == "1"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(1 == sequences):
? ? ? ? ? ? if(answer == "3"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(2 == sequences):
? ? ? ? ? ? if(answer == "2"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1
? ? # Stopping the time of the clock
? ? b = datetime.datetime.now().replace(microsecond=0)
? ? # displaying number of wrong answer and total quiz time
? ? print "Total Number of Wrong Answer:", wrongAnswer
? ? print "Total Quiz Time", (b-a)
? ? print "Total Number of correct Answer", correctAnswerCounter
? ? #asking user to reenter
? ? restart= raw_input("Do You want to start the quiz again Yes or No")
? ? if(restart=="no"):
? ? ? ? print "Thanks for quiz"
? ? ? ? break;
? ? elif(restart=="yes"):
? ? ? ? wrongAnswer=0
? ? ? ? correctAnswerCounter=0;
? ? ? ? correctAnswer=[];
? ? ? ? i=0
? ? ? ? while (i<(counter/2)):
? ? ? ? ? ? i=i+1
? ? ? ? ? ? correctAnswer.append(0)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140113/4ec239fa/attachment-0001.html>

From dyoo at hashcollision.org  Mon Jan 13 20:25:14 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Mon, 13 Jan 2014 11:25:14 -0800
Subject: [Tutor] how to use 2to3
In-Reply-To: <1389634201.66114.YahooMailNeo@web133101.mail.ir2.yahoo.com>
References: <1389634201.66114.YahooMailNeo@web133101.mail.ir2.yahoo.com>
Message-ID: <CAGZAPF5w1xFt757cGB-s9A1LtySYuT1tPzVKWpa=iEsdjMPf5A@mail.gmail.com>

On Mon, Jan 13, 2014 at 9:30 AM, S Tareq <stareq13 at yahoo.com> wrote:
> can you please help me how to use 2to3 on 3.3. i went to the web site follow
> instraction and it did not work.

When asking for debugging help, it is usually a very good idea to
provide as much detail about what you exactly did as you can.
Specifically, if you see an error message, copy and paste the error
message for people to see.  If you are running a set of commands, copy
and paste exactly what commands you are running.

Why is this important?  Because the people who want to help you will
need to _replicate_ the steps that you are doing.  Maybe you have made
a mistake in typing something.  Or maybe you've forgotten a step.
Without seeing what steps you have taken, we can not tell.

Or, in some cases, maybe the software itself is at fault.  Maybe the
problem is something entirely external.  Computers are complicated,
and a lot of things can break.  Again, we can not know that without
seeing the error message you are encountering as well.

So please provide more information.  Otherwise, we can not help you:
we simply don't have enough information!


According to:

    http://docs.python.org/2/library/2to3.html

you should be able to transform Python 2 programs to Python 3 programs
using the 2to3 program.


When I run the program 2to3 on your sample program, everything appears
to work fine.

################################################
dannyyoo at melchior:~$ 2to3 -w program.py
RefactoringTool: Skipping implicit fixer: buffer
RefactoringTool: Skipping implicit fixer: idioms
RefactoringTool: Skipping implicit fixer: set_literal
RefactoringTool: Skipping implicit fixer: ws_comma
RefactoringTool: Refactored foo.py
... [output omitted]
#################################################

and the resulting program.py does appear to use Python 3 conventions.


So I can not replicate or verify what you are seeing.

From alan.gauld at btinternet.com  Mon Jan 13 20:27:41 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 13 Jan 2014 19:27:41 +0000
Subject: [Tutor] another better way to do this ?
In-Reply-To: <lb1aru$k8h$1@ger.gmane.org>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org> <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
 <lau9in$no0$2@ger.gmane.org> <lausti$96l$1@ger.gmane.org>
 <lautgh$ff4$1@ger.gmane.org> <lauvc6$3pk$1@ger.gmane.org>
 <lav0oi$ft2$1@ger.gmane.org> <lb1aru$k8h$1@ger.gmane.org>
Message-ID: <lb1en1$4h4$1@ger.gmane.org>

On 13/01/14 18:22, Peter Otten wrote:
> Peter Otten wrote:

> In the mean time here is my candidate:
>
> def test(a, b):
>      a = iter(a)
>      return all(c in a for c in b)

That's pretty close to my original thoughts. But one question.
Why explicitly convert string a to an iter? The 'in' test
would work with the original string. What extra magic does
iter confer? Or are you extending reuse beyond strings?

And of course the original challenge was not for a
boolean result but a specific string result so I'd
go with:

def test(a,b):
    return {True: b,
            False: 'Give me something that's not useless next time.'
           }[all(c in a for c in b)]

or even

def test(a,b)
     return b if all(c in a for c in b) else "Give me something that's 
not useless next time."

Are we there yet? :-)
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From eryksun at gmail.com  Mon Jan 13 20:34:34 2014
From: eryksun at gmail.com (eryksun)
Date: Mon, 13 Jan 2014 14:34:34 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <CAO5ffbb9oaWr8j1jdDWcAnZYER4NSqv8+M=Z-iwooT9K2vaZPg@mail.gmail.com>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau9in$no0$2@ger.gmane.org>
 <lausti$96l$1@ger.gmane.org> <lautgh$ff4$1@ger.gmane.org>
 <lauvc6$3pk$1@ger.gmane.org>
 <lav0oi$ft2$1@ger.gmane.org> <lb1aru$k8h$1@ger.gmane.org>
 <CAO5ffbb9oaWr8j1jdDWcAnZYER4NSqv8+M=Z-iwooT9K2vaZPg@mail.gmail.com>
Message-ID: <CACL+1at2rUc5Xn5oiR6w2u7DQ8v2n2zULHQkquWkVkCQdtf2qg@mail.gmail.com>

On Mon, Jan 13, 2014 at 1:36 PM, Keith Winston <keithwins at gmail.com> wrote:
> Yikes, Peter, that's scary. Wow.

Yikes, watch the top posting. :)

>> In the mean time here is my candidate:
>>
>> def test(a, b):
>>     a = iter(a)
>>     return all(c in a for c in b)

Refer to the language reference discussion of comparison expressions:

http://docs.python.org/3/reference/expressions.html#not-in

    For user-defined classes which do not define __contains__() but
    do define __iter__(), x in y is true if some value z with
    x == z is produced while iterating over y.

Since the iterator returned by `iter(a)` doesn't implement
__contains__, the interpreter iterates it looking for a match for `c`.
In effect, Peter smuggled a state variable into the expression,
equivalent to `index` in your code.

CPython Implementation
The "in" comparison operator is implemented abstractly by
PySequence_Contains. If the type doesn't define sq_contains, then the
call is routed to _PySequence_IterSearch, which calls PyIter_Next
until it either finds a match or the iterator is exhausted.

From __peter__ at web.de  Mon Jan 13 20:55:49 2014
From: __peter__ at web.de (Peter Otten)
Date: Mon, 13 Jan 2014 20:55:49 +0100
Subject: [Tutor] another better way to do this ?
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org> <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl>
 <lau9in$no0$2@ger.gmane.org> <lausti$96l$1@ger.gmane.org>
 <lautgh$ff4$1@ger.gmane.org> <lauvc6$3pk$1@ger.gmane.org>
 <lav0oi$ft2$1@ger.gmane.org> <lb1aru$k8h$1@ger.gmane.org>
 <lb1en1$4h4$1@ger.gmane.org>
Message-ID: <lb1gbn$p34$1@ger.gmane.org>

Alan Gauld wrote:

> On 13/01/14 18:22, Peter Otten wrote:
>> Peter Otten wrote:
> 
>> In the mean time here is my candidate:
>>
>> def test(a, b):
>>      a = iter(a)
>>      return all(c in a for c in b)
> 
> That's pretty close to my original thoughts. But one question.
> Why explicitly convert string a to an iter? The 'in' test
> would work with the original string. What extra magic does
> iter confer? Or are you extending reuse beyond strings?

No, I wanted to give a solution for the problem as originally stated and as 
attacked by Emile, where all characters have to occur in a in the same order 
as in b, but with arbitrary garbage allowed in between. Compare:

>>> for debris, product in [("alph", "alpha"), ("alpha", "alpha"), 
("axlypzha", "alpha"), ("alpha", "alpha"[::-1])]:
...     print("debris: {}, product: {} --> test(): {}, (...): {}".format(
...         debris, product, test(debris, product), all(c in debris for c in 
product)))
... 
debris: alph, product: alpha --> test(): False, (...): True
debris: alpha, product: alpha --> test(): True, (...): True
debris: axlypzha, product: alpha --> test(): True, (...): True
debris: alpha, product: ahpla --> test(): False, (...): True

The all(...) expression alone gets neither the count nor the order right.
The iter() call causes the `c in a` expression to search for the current c 
only after the occurence of the previous c. 

> And of course the original challenge was not for a
> boolean result but a specific string result so I'd
> go with:
> 
> def test(a,b):
>     return {True: b,
>             False: 'Give me something that's not useless next time.'
>            }[all(c in a for c in b)]
> 
> or even
> 
> def test(a,b)
>      return b if all(c in a for c in b) else "Give me something that's
> not useless next time."
> 
> Are we there yet? :-)

Where's there? When's yet?

;)


From keithwins at gmail.com  Mon Jan 13 21:15:26 2014
From: keithwins at gmail.com (Keith Winston)
Date: Mon, 13 Jan 2014 15:15:26 -0500
Subject: [Tutor] another better way to do this ?
In-Reply-To: <lb1gbn$p34$1@ger.gmane.org>
References: <DUB121-W291ADF83E186A916ED03C4AEB20@phx.gbl>
 <lasoib$uo9$1@ger.gmane.org>
 <DUB121-W796DCA30F851CE2A96F29AEBD0@phx.gbl> <lau9in$no0$2@ger.gmane.org>
 <lausti$96l$1@ger.gmane.org> <lautgh$ff4$1@ger.gmane.org>
 <lauvc6$3pk$1@ger.gmane.org>
 <lav0oi$ft2$1@ger.gmane.org> <lb1aru$k8h$1@ger.gmane.org>
 <lb1en1$4h4$1@ger.gmane.org> <lb1gbn$p34$1@ger.gmane.org>
Message-ID: <CAO5ffbbnR_7952SiYF3g86ZaDHsb4SXLRnTpnmFibJG+=4+9Ug@mail.gmail.com>

s*** just got real.

From breamoreboy at yahoo.co.uk  Mon Jan 13 21:27:14 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Mon, 13 Jan 2014 20:27:14 +0000
Subject: [Tutor] how to use 2to3
In-Reply-To: <1389634201.66114.YahooMailNeo@web133101.mail.ir2.yahoo.com>
References: <1389634201.66114.YahooMailNeo@web133101.mail.ir2.yahoo.com>
Message-ID: <lb1i6m$fo3$1@ger.gmane.org>

On 13/01/2014 17:30, S Tareq wrote:
> can you please help me how to use 2to3 on 3.3. i went to the web site
> follow instraction and it did not work.
>

Providing a sizeable wedge of code and stating "it did not work" is 
pretty useless.  But I'd guess that you've run the code *WITHOUT* the -w 
flag.  Am I correct?  You could have found this out for yourself by 
using this command:-

2to3 --help

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

Mark Lawrence


From christian.h.alexander at gmail.com  Tue Jan 14 08:42:07 2014
From: christian.h.alexander at gmail.com (Christian Alexander)
Date: Tue, 14 Jan 2014 02:42:07 -0500
Subject: [Tutor] Interactive escape sequences
Message-ID: <CABSj3_655qSsrWunEdwiQ2ke0T7Nwxzvy1XrkgQZiridoy9DWQ@mail.gmail.com>

Hello Tutorians,

Why does the interactive prompt not recognize escape sequences in strings?
 It only works correctly if I use the print function in python 3.

>>> "Hello\nWorld"
"Hello\nWorld"

-- 
Regards,

Christian Alexander
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140114/fb5e805d/attachment-0001.html>

From kukulies at physik.rwth-aachen.de  Tue Jan 14 09:22:54 2014
From: kukulies at physik.rwth-aachen.de (Krischu)
Date: Tue, 14 Jan 2014 00:22:54 -0800 (PST)
Subject: [Tutor] iPython notebook In [*]:  numbering
Message-ID: <1389687774536-5043985.post@n6.nabble.com>

Hi,

I'm new to python and ipython. After the first steps I did I found that the
numbering scheme in the Webapp (notebook) is kind of unpredicatble.
 
When I started I had In [0]:, In[1] etc.

Now the notebook starts with In [2]:, In [3]: then In [9]:

Yesterday before storing and leaving the notebook I suddenly had all In[]'s
marked like In [*]:

Is there a method behind this? Can one reorder/garbage collect the notebook?

Thanks

--
Christoph




--
View this message in context: http://python.6.x6.nabble.com/iPython-notebook-In-numbering-tp5043985.html
Sent from the Python - tutor mailing list archive at Nabble.com.

From alan.gauld at btinternet.com  Tue Jan 14 10:22:04 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 14 Jan 2014 09:22:04 +0000
Subject: [Tutor] Interactive escape sequences
In-Reply-To: <CABSj3_655qSsrWunEdwiQ2ke0T7Nwxzvy1XrkgQZiridoy9DWQ@mail.gmail.com>
References: <CABSj3_655qSsrWunEdwiQ2ke0T7Nwxzvy1XrkgQZiridoy9DWQ@mail.gmail.com>
Message-ID: <lb2vjf$7cc$1@ger.gmane.org>

On 14/01/14 07:42, Christian Alexander wrote:

> Why does the interactive prompt not recognize escape sequences in
> strings?  It only works correctly if I use the print function in python 3.
>
>  >>> "Hello\nWorld"
> "Hello\nWorld"

That depends on how you define "correctly"...

When you evaluate an expression at the Python prompt Python prints the 
repr() of the value. For strings that includes the quotes and the \n 
characters  and any other special characters it finds. The print 
function on the other hand prints the str() of the value and that 
interprets the quotes etc out

In general repr() is more useful for debugging since it shows any 
'hidden' whitespace characters. repr() by convention should return a 
value that can be evaluated and assigned to a variable, although it 
doesn't always do that for miore complex types.

hth
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From davea at davea.name  Tue Jan 14 11:11:04 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 14 Jan 2014 05:11:04 -0500 (EST)
Subject: [Tutor] Interactive escape sequences
References: <CABSj3_655qSsrWunEdwiQ2ke0T7Nwxzvy1XrkgQZiridoy9DWQ@mail.gmail.com>
 <lb2vjf$7cc$1@ger.gmane.org>
Message-ID: <lb32bb$6el$1@ger.gmane.org>

 Alan Gauld <alan.gauld at btinternet.com> Wrote in message:
> On 14/01/14 07:42, Christian Alexander wrote:
> 
>> Why does the interactive prompt not recognize escape sequences in
>> strings?  It only works correctly if I use the print function in python 3.
>>
>>  >>> "Hello\nWorld"
>> "Hello\nWorld"
> 
> That depends on how you define "correctly"...
> 
> When you evaluate an expression at the Python prompt Python prints the 
> repr() of the value. For strings that includes the quotes and the \n 
> characters  and any other special characters it finds. The print 
> function on the other hand prints the str() of the value and that 
> interprets the quotes etc out
> 
> In general repr() is more useful for debugging since it shows any 
> 'hidden' whitespace characters. repr() by convention should return a 
> value that can be evaluated and assigned to a variable, although it 
> doesn't always do that for miore complex types.
> 

I'd like to elaborate,  Christian.   The escape sequence in the
 literal string has been processed by the interpreter in either
 case by the time the string object has been created. What makes
 the repr logic important is that it adds the quotation marks, and
 turns unprintables into escape sequences.  It has absolutely no
 access to the literal you started with.

See for example

"""this
one"""

or

"\x41"




-- 
DaveA



----Android NewsGroup Reader----
http://www.piaohong.tk/newsgroup


From __peter__ at web.de  Tue Jan 14 14:18:00 2014
From: __peter__ at web.de (Peter Otten)
Date: Tue, 14 Jan 2014 14:18 +0100
Subject: [Tutor] Interactive escape sequences
References: <CABSj3_655qSsrWunEdwiQ2ke0T7Nwxzvy1XrkgQZiridoy9DWQ@mail.gmail.com>
Message-ID: <lb3ddr$828$1@ger.gmane.org>

Christian Alexander wrote:

> Hello Tutorians,
> 
> Why does the interactive prompt not recognize escape sequences in strings?
>  It only works correctly if I use the print function in python 3.
> 
>>>> "Hello\nWorld"
> "Hello\nWorld"

The way python shows objects in the interactive interpreter has been found 
the most useful for the intended purpose -- to explore python objects and to 
provide a debugging aid. But you can customise the behaviour by defining 
your own displayhook:

>>> import builtins
>>> import sys
>>> def dh(obj):
...     if obj is not None:
...             builtins._ = obj
...             print(obj)
... 
>>> sys.displayhook = dh
>>> "hello\nworld"
hello
world


For a more robust version as a possible starting point for your own efforts 
see:

http://docs.python.org/dev/library/sys.html#sys.displayhook

Personally, I recommend that you use the interactive interpreter as is some 
more -- it'll grow on you. 

You may also give IPython <http://ipython.org/> a try.


From eryksun at gmail.com  Tue Jan 14 14:34:13 2014
From: eryksun at gmail.com (eryksun)
Date: Tue, 14 Jan 2014 08:34:13 -0500
Subject: [Tutor] Interactive escape sequences
In-Reply-To: <CABSj3_655qSsrWunEdwiQ2ke0T7Nwxzvy1XrkgQZiridoy9DWQ@mail.gmail.com>
References: <CABSj3_655qSsrWunEdwiQ2ke0T7Nwxzvy1XrkgQZiridoy9DWQ@mail.gmail.com>
Message-ID: <CACL+1atg_wpsmhc9duEH5CA_SPfY5eK198KZ5kPSmESJJUvvmQ@mail.gmail.com>

On Tue, Jan 14, 2014 at 2:42 AM, Christian Alexander
<christian.h.alexander at gmail.com> wrote:
>
> Why does the interactive prompt not recognize escape sequences in strings?
> It only works correctly if I use the print function in python 3.
>
>>>> "Hello\nWorld"
> "Hello\nWorld"

Let's manually compile the following source string:

    src = r'"Hello\n"'

Here's how the input would look when typed at the prompt:

    >>> print(src)
    "Hello\n"

Compile it with the dummy filename of '<stdin>' and in 'single' mode,
as is done for the interactive prompt:

    >>> code = compile(src, '<stdin>', 'single')

Then disassemble the code object:

    >>> dis.dis(code)
      1           0 LOAD_CONST               0 ('Hello\n')
                  3 PRINT_EXPR
                  4 LOAD_CONST               1 (None)
                  7 RETURN_VALUE

The string literal is constant 0 in the code object. Constants are
stored in the code's `co_consts` tuple. Let's map `ord` to the string:

    >>> print(*[(c, ord(c)) for c in code.co_consts[0]], sep='\n')
    ('H', 72)
    ('e', 101)
    ('l', 108)
    ('l', 108)
    ('o', 111)
    ('\n', 10)

As you can see, '\n' is used to represent the linefeed control
character, which has Unicode ordinal 10 (0x0A). It's a convenient
representation that you can actually evaluate using `eval` or `exec`.
Not all object representations have this evaluation property. For
example, the representation of an io file object can't be evaluated.
But simple types usually support this ability.

Refer back to the disassembled code object. It loads the string
constant onto the stack. Then it executes the instruction PRINT_EXPR.
This instruction in turn calls `sys.displayhook`, which defaults to a
built-in function that prints the representation of the object and
stores a reference to it as `_` in the builtins namespace.

Feel free to replace the `sys.displayhook` function if you don't like
the default output. Off the top of my head, here's a function that
uses `print` instead, and stores previously printed results in a list:

    def mydisplayhook(obj):
        import builtins
        if not (hasattr(builtins, '_') and
                isinstance(builtins._, list)):
            builtins._ = []
        if obj is not None and obj is not builtins._:
            builtins._.append(obj)
        print(obj) # usr str instead of repr

    >>> import sys
    >>> sys.displayhook = mydisplayhook

    >>> "Hello\n"
    Hello

    >>> 1
    1
    >>> 2
    2
    >>> 3
    3
    >>> _
    ['Hello\n', 1, 2, 3]

From steve at pearwood.info  Tue Jan 14 14:35:20 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 15 Jan 2014 00:35:20 +1100
Subject: [Tutor] Interactive escape sequences
In-Reply-To: <CABSj3_655qSsrWunEdwiQ2ke0T7Nwxzvy1XrkgQZiridoy9DWQ@mail.gmail.com>
References: <CABSj3_655qSsrWunEdwiQ2ke0T7Nwxzvy1XrkgQZiridoy9DWQ@mail.gmail.com>
Message-ID: <20140114133519.GH3869@ando>

On Tue, Jan 14, 2014 at 02:42:07AM -0500, Christian Alexander wrote:
> Hello Tutorians,
> 
> Why does the interactive prompt not recognize escape sequences in strings?
>  It only works correctly if I use the print function in python 3.
> 
> >>> "Hello\nWorld"
> "Hello\nWorld"

I'm afraid that you are misinterpreting what you are seeing. Regardless 
of whether you use the interactive prompt or not, or whether you print 
the string, the string "Hello\nWorld" contains the words "Hello" and 
"World" separated by a newline.

What happens when you display the string?

When you use print, it gets printed to the screen, which means that 
newline actually causes a new line. In addition, tabs cause the text to 
be indented. So:

py> s = "Hello\nWorld\t!"
py> print s
Hello
World   !


But in addition to just printing the string, we can print the 
*representation* of the string, which shows control characters in 
escaped form and includes quotation marks:

py> print repr(s)
'Hello\nWorld\t!'


You'll notice that the repr() of the string is just like what you typed 
as a string literal, except that I typed double quotes " and Python uses 
single quotes ' by default.

What happens if we don't use print, but just enter the string?

py> s
'Hello\nWorld\t!'


The interactive interpreter chooses to display the repr() of the string, 
rather than print the string. The reason for this is that, in general, 
it is more useful to see the repr() while debugging or experimenting 
interactively, and if you wish to the see the printed version of the 
string, it's easy enough to use print.


Note: my examples above are using Python 2. In Python 3, you need to 
use round brackets after the print, e.g. "print(s)".



-- 
Steven

From eryksun at gmail.com  Tue Jan 14 15:27:27 2014
From: eryksun at gmail.com (eryksun)
Date: Tue, 14 Jan 2014 09:27:27 -0500
Subject: [Tutor] iPython notebook In [*]: numbering
In-Reply-To: <1389687774536-5043985.post@n6.nabble.com>
References: <1389687774536-5043985.post@n6.nabble.com>
Message-ID: <CACL+1av25vn9x_k4Tb8xZnDnFfEUV66VM6HheiQ35+cxnmoFfQ@mail.gmail.com>

On Tue, Jan 14, 2014 at 3:22 AM, Krischu <kukulies at physik.rwth-aachen.de> wrote:
> When I started I had In [0]:, In[1] etc.
>
> Now the notebook starts with In [2]:, In [3]: then In [9]:
>
> Yesterday before storing and leaving the notebook I suddenly had all In[]'s
> marked like In [*]:
>
> Is there a method behind this? Can one reorder/garbage collect the notebook?

Did you try restarting the kernel and then recalculating the cells?

    Kernel => Restart
      Cell => Run All

From xgrace_robertsx at hotmail.co.uk  Tue Jan 14 19:40:03 2014
From: xgrace_robertsx at hotmail.co.uk (Grace Roberts)
Date: Tue, 14 Jan 2014 18:40:03 +0000
Subject: [Tutor] Problems using odeint
Message-ID: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>

Hi,
I'm a python beginner, currently using scipy's 'odeint' to compute to a set of ODEs (obtained by splitting Newton's law of gravity ma=-Gm1m2r/r^3 in two ordinary differentials). The idea is that I'm modelling the orbit of a satellite as it approaches Mars.
I have two problems:-For certain initial conditions the programme displays impossible orbits, showing the satellite making immediate sharp turns or jumping up and down in velocity. The exact same code can also end up displaying different graphs when run multiple times. For example when initial conditions are set at:  xx0=[1000.,10000.,1000.,10000.].-Often when run an error message appears saying: "Excess work done on this call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative information." You can see that as part of the odeint function I tried to stop the excess work by increasing the maxstep and I also tried to run with full_output =1. It's quite possible I haven't done this right. If I have, what else can I do to stop this message from appearing?
I've attached a quick print-screen of the code.
Any help is much appreciated. 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140114/89ac379d/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: print screen3.docx
Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Size: 138247 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/tutor/attachments/20140114/89ac379d/attachment-0001.docx>

From joel.goldstick at gmail.com  Wed Jan 15 00:02:44 2014
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Tue, 14 Jan 2014 18:02:44 -0500
Subject: [Tutor] Problems using odeint
In-Reply-To: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
References: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
Message-ID: <CAPM-O+wZSY=1R7tgiGh8f1YMimAMAxEGJGEOU0U2JJU_8LBLUg@mail.gmail.com>

On Tue, Jan 14, 2014 at 1:40 PM, Grace Roberts
<xgrace_robertsx at hotmail.co.uk> wrote:
> Hi,
>
> I'm a python beginner, currently using scipy's 'odeint' to compute to a set
> of ODEs (obtained by splitting Newton's law of gravity ma=-Gm1m2r/r^3 in two
> ordinary differentials). The idea is that I'm modelling the orbit of a
> satellite as it approaches Mars.
>
> I have two problems:
> -For certain initial conditions the programme displays impossible orbits,
> showing the satellite making immediate sharp turns or jumping up and down in
> velocity. The exact same code can also end up displaying different graphs
> when run multiple times. For example when initial conditions are set at:
> xx0=[1000.,10000.,1000.,10000.].
> -Often when run an error message appears saying: "Excess work done on this
> call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative
> information." You can see that as part of the odeint function I tried to
> stop the excess work by increasing the maxstep and I also tried to run with
> full_output =1. It's quite possible I haven't done this right. If I have,
> what else can I do to stop this message from appearing?
>
> I've attached a quick print-screen of the code.
>
> Any help is much appreciated.
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

Sorry I can't help you, but the way it works best here is that you
actually cut and paste your code in your email.  Use text mode, not
html.  Then run your code, and cut and paste the traceback to your
email.

-- 
Joel Goldstick
http://joelgoldstick.com

From steve at pearwood.info  Wed Jan 15 01:08:51 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 15 Jan 2014 11:08:51 +1100
Subject: [Tutor] Problems using odeint
In-Reply-To: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
References: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
Message-ID: <20140115000851.GI3869@ando>

Hi Grace, and welcome,

My reply is interleaved with your comments.

On Tue, Jan 14, 2014 at 06:40:03PM +0000, Grace Roberts wrote:
> Hi,
> I'm a python beginner, currently using scipy's 'odeint' to compute to 
> a set of ODEs (obtained by splitting Newton's law of gravity 
> ma=-Gm1m2r/r^3 in two ordinary differentials). The idea is that I'm 
> modelling the orbit of a satellite as it approaches Mars. 

Unfortunately, I don't think there is anyone here who is very familiar 
with scipy. Including me. I'll try my best to give some helpful 
comments, but take them with a grain of salt.


> I have two 
> problems:-For certain initial conditions the programme displays 
> impossible orbits, showing the satellite making immediate sharp turns 
> or jumping up and down in velocity.

I'm not an expert on numeric code, but my first instinct on reading this 
is to think that you're suffering numerical instability in your ODEs. 
It's been too many years since I've done ODEs to be much help to you 
here, but can you double check that the ODE you are using is 
mathematically correct and any constants are expressed to sufficient 
accuracy?


> The exact same code can also end 
> up displaying different graphs when run multiple times. For example 
> when initial conditions are set at: 
> xx0=[1000.,10000.,1000.,10000.].

If what you say is accurate, that strongly suggests that the system you 
are modelling is chaotic, and tiny changes in initial conditions lead to 
major changes in the output. This problem may be inherent in the 
physical system.


> -Often when run an error message 
> appears saying: "Excess work done on this call (perhaps wrong Dfun 
> type). Run with full_output = 1 to get quantitative information." You 
> can see that as part of the odeint function I tried to stop the excess 
> work by increasing the maxstep and I also tried to run with 
> full_output =1. It's quite possible I haven't done this right. If I 
> have, what else can I do to stop this message from appearing? I've 
> attached a quick print-screen of the code. Any help is much 
> appreciated.

Unfortunately print-screen is not so helpful here. What we really need 
is your code copy and pasted as text, if possible directly in the body 
of your email. If it is more than a hundred lines or so, it will 
probably be better to attach your .py file to the email.

I will try to find a program that will let me view your .docx file (like 
many of us here, I'm a Linux user and don't have access to Microsoft 
Office) so I can at least see the print-screen, but being able to access 
it as text rather than just a screenshot would make it much easier to 
help you.

Regards,


-- 
Steven

From dyoo at hashcollision.org  Wed Jan 15 01:16:29 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 14 Jan 2014 16:16:29 -0800
Subject: [Tutor] Problems using odeint
In-Reply-To: <CAPM-O+wZSY=1R7tgiGh8f1YMimAMAxEGJGEOU0U2JJU_8LBLUg@mail.gmail.com>
References: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
 <CAPM-O+wZSY=1R7tgiGh8f1YMimAMAxEGJGEOU0U2JJU_8LBLUg@mail.gmail.com>
Message-ID: <CAGZAPF7hzVLf0efgogHgmviLntqoaYop0NQcno13VV4EoSYskA@mail.gmail.com>

Hi Grace,


I see that you're asking about the behavior of scipy.integrate.odeint():

   http://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.odeint.html#scipy.integrate.odeint

Unfortunately this might be too domain specific of a question for
folks here at Tutor.  I don't see anything in the source code
screenshot that is ringing any warnings in my head.

(As Joel notes, please do a copy-and-paste of the textual content of
your program into the email next time.  Screenshots are significantly
harder for people to look at.)


You may want to ask your question on a mailing list specific to SciPy;
the audience there may have more familiarity with the gotcha you're
running into.  You can find out about the SciPy-user mailing list at:

    http://www.scipy.org/scipylib/mailing-lists.html#mailing-lists

From steve at pearwood.info  Wed Jan 15 01:51:38 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 15 Jan 2014 11:51:38 +1100
Subject: [Tutor] Problems using odeint
In-Reply-To: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
References: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
Message-ID: <20140115005138.GJ3869@ando>

On Tue, Jan 14, 2014 at 06:40:03PM +0000, Grace Roberts wrote:
[...]
> I've attached a quick print-screen of the code.

I've managed to have a look at the screenshot, there are no obvious 
problems, but I'm not a Scipy expert. If you do get an answer from a 
Scipy mailing list, I would really appreciate it if you were to write 
back here with an explanation.

In the meantime, I have a couple of comments about your code. You 
initialise some constants like this:

G = -6.67*10**-11
Mm = 6.4*10**23

You can write them more compactily as:

G = -6.67e-11
Mm = 6.4e23


Notice that you have made G a negative value? That is unusual, normally 
G is quoted as a positive quantity, G = 6.67e-11 m?/(kg*s?), or the same 
value with units N (m/kg)?. Either way, G is given a positive value. 
Possibly making G a negative quantity is causing the problems?


Another minor comment on your code, in the f(x, t) function you have a
line taking a square root:

r = (x[0]**2 + x[2]**2)**0.5


You can improve the accuracy of that radius calculation by using 
the hypot function. First, at the top of the file, import 
the math module:

import math


Then inside the f(x,t) function change the calculation of r to this:

r = math.hypot(x[0], x[2])


Hope this is helpful,



-- 
Steven

From eryksun at gmail.com  Wed Jan 15 07:42:56 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 15 Jan 2014 01:42:56 -0500
Subject: [Tutor] Problems using odeint
In-Reply-To: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
References: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
Message-ID: <CACL+1atP5rHqwX3Oz+rpRKABxe4fsTjf7tCBA5DRsBK2KVm1Rg@mail.gmail.com>

On Tue, Jan 14, 2014 at 1:40 PM, Grace Roberts
<xgrace_robertsx at hotmail.co.uk> wrote:
>
> -For certain initial conditions the programme displays impossible orbits,
> showing the satellite making immediate sharp turns or jumping up and down in
> velocity. The exact same code can also end up displaying different graphs
> when run multiple times. For example when initial conditions are set at:
> xx0=[1000.,10000.,1000.,10000.].

The trajectory is decaying into the planet. In real life it hits the
surface. In the model it continues until the radius is 0. As the
radius approaches zero, odeint will have problems converging.

I ran your calculation for Phobos, assuming a perfectly circular
orbit. I started with `Rsx == Rxy` and `Vsx = -Vsy`. It steps through
a cycle in the expected time.

https://en.wikipedia.org/wiki/Phobos_%28moon%29

Output Plot:
http://i.imgur.com/Jh0sbnT.png


    import numpy as np
    from scipy import integrate
    import matplotlib.pyplot as plt

    G = 6.674e-11
    Mm = 6.4185e23  # Mars mass
    Rs = 9.376e6    # Phobos orbit semi-major axis
    Vs = 2.138e3    # Phobos orbit average velocity
    Ts = 2.7554e4   # Phobos orbit period

    def f(y, t):
        rx, ry, vx, vy = y
        r = np.hypot(rx, ry)
        ax = -G * Mm * rx / r ** 3
        ay = -G * Mm * ry / r ** 3
        return vx, vy, ax, ay

    Rsx = Rsy = (Rs ** 2 / 2) ** 0.5
    Vsy = (Vs ** 2 / 2) ** 0.5
    Vsx = -Vsy
    y0 = [Rsx, Rsy, Vsx, Vsy]

    t = np.linspace(0, Ts, Ts * 10)

    y, info = integrate.odeint(f, y0, t, full_output=1)
    rx, ry, vx, vy = y.T

    plt.subplot(211)
    plt.title('Position')
    plt.plot(t, rx, t, ry)
    plt.grid(); plt.axis('tight')
    plt.subplot(212)
    plt.title('Velocity')
    plt.plot(t, vx, t, vy)
    plt.grid(); plt.axis('tight')
    plt.show()

From eryksun at gmail.com  Wed Jan 15 09:11:58 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 15 Jan 2014 03:11:58 -0500
Subject: [Tutor] Problems using odeint
In-Reply-To: <CACL+1atP5rHqwX3Oz+rpRKABxe4fsTjf7tCBA5DRsBK2KVm1Rg@mail.gmail.com>
References: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
 <CACL+1atP5rHqwX3Oz+rpRKABxe4fsTjf7tCBA5DRsBK2KVm1Rg@mail.gmail.com>
Message-ID: <CACL+1ash0VBeUKFor=7Uy3j2MPpK3zLFfCES94s6t555NGAJvw@mail.gmail.com>

On Wed, Jan 15, 2014 at 1:42 AM, eryksun <eryksun at gmail.com> wrote:
>
> The trajectory is decaying into the planet. In real life it hits the
> surface.

Not quite. A radius of 1.4 km is inside the planet, so that's
unrealistic from the start. If it starts at the surface of Mars, at
around 3,400 km, then the satellite needs at least the following
escape velocity:

    >>> (2 * G * Mm / 3.4e6) ** 0.5
    5019.788430038953

Otherwise it eventually crashes back on the surface.

From steve at pearwood.info  Wed Jan 15 12:06:32 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 15 Jan 2014 22:06:32 +1100
Subject: [Tutor] Tutor Digest, Vol 115, Issue 28
In-Reply-To: <laso3c$qc3$1@ger.gmane.org>
References: <mailman.2095.1379016934.5460.tutor@python.org>
 <CAKSTmRDWd0rZrp-rTUmzzVLyFH1D4ZPb+4G4__o+LAWp0psvYQ@mail.gmail.com>
 <laso3c$qc3$1@ger.gmane.org>
Message-ID: <20140115110632.GO3869@ando>

On Sun, Jan 12, 2014 at 12:37:12AM +0000, Alan Gauld wrote:

> As to your question. The best advice is to read what you type
> carefully.
> And know what you are trying to do before you type it.
> In other words, think about the design of your code don't
> just type randomly. That way you are less likely to
> get random errors.

This is excellent advise for all but the smallest, simplest, and most 
obvious programs. You should *design* the program before you *write* the 
program.

You might even discover that you can avoid writing the program in the 
first place!

Design doesn't need to be complicated. For example, if I'm designing a 
function, sometimes all I need do is think about what I want it to do, 
then write the documentation first. So I write:

def download_from_internet(url):
    """Download text or data from a URL.

    >>> text = download_from_internet("http://example.com")
    >>> print(text)
    "Hello"

    """
    pass


These few lines are a perfectly good design, at least for a first draft. 
By writing it down, I get to see how I expect to use this function, and 
the expected results, which helps me decide:

- Is this a good name for the function?

  Answer: no, because it's not just from the Internet that it can 
  download, it can download from local web servers, or even local
  files on my hard drive using the "file://" protocol.

- Is the function well thought-out? What job does it do?

  Answer: partly. It is useful for downloading data into a variable, but 
  what if I just want to download a file and save to disk? Perhaps that
  should be a separate function?

- Is the function's job well defined?

  Answer: not really. I talk about downloading "text or data", but that 
  requires slightly different handling. With text, for example, I need 
  to consider what encoding the text is (e.g. is it ASCII, or Unicode, 
  or Latin-1?), but with binary data, I mustn't convert anything.


So this helps me design a better function, before I have written a 
single line of code except for the function definition header line.



-- 
Steven

From steve at pearwood.info  Wed Jan 15 12:12:15 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 15 Jan 2014 22:12:15 +1100
Subject: [Tutor] Tutor Digest, Vol 115, Issue 28
In-Reply-To: <CAO5ffbbHdpHDZuOcs5z-5T+BQFMTkM+Tq8wAG7b97RJ_UC17sQ@mail.gmail.com>
References: <mailman.2095.1379016934.5460.tutor@python.org>
 <CAKSTmRDWd0rZrp-rTUmzzVLyFH1D4ZPb+4G4__o+LAWp0psvYQ@mail.gmail.com>
 <laso3c$qc3$1@ger.gmane.org>
 <CAO5ffbbHdpHDZuOcs5z-5T+BQFMTkM+Tq8wAG7b97RJ_UC17sQ@mail.gmail.com>
Message-ID: <20140115111215.GP3869@ando>

On Sun, Jan 12, 2014 at 02:02:48AM -0500, Keith Winston wrote:
> On Sat, Jan 11, 2014 at 7:37 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> > In other words, think about the design of your code don't
> > just type randomly.
> 
> 
> I prefer the "million monkeys at a million typewriters" approach to
> coding...  But then, it's all I've tried...

You're selling youself short. From what I've seen of you on this list, 
you might be a beginner, but you've got the right sort of inquiring mind 
to go far as a programmer.


-- 
Steven

From oscar.j.benjamin at gmail.com  Wed Jan 15 12:24:52 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Wed, 15 Jan 2014 11:24:52 +0000
Subject: [Tutor] Problems using odeint
In-Reply-To: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
References: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
Message-ID: <20140115112449.GA4952@gmail.com>

On Tue, Jan 14, 2014 at 06:40:03PM +0000, Grace Roberts wrote:
> Hi,
> I'm a python beginner, currently using scipy's 'odeint' to compute to a set of ODEs (obtained by splitting Newton's law of gravity ma=-Gm1m2r/r^3 in two ordinary differentials). The idea is that I'm modelling the orbit of a satellite as it approaches Mars.
> I have two problems:-For certain initial conditions the programme displays impossible orbits, showing the satellite making immediate sharp turns or jumping up and down in velocity. The exact same code can also end up displaying different graphs when run multiple times. For example when initial conditions are set at:  xx0=[1000.,10000.,1000.,10000.].-Often when run an error message appears saying: "Excess work done on this call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative information." You can see that as part of the odeint function I tried to stop the excess work by increasing the maxstep and I also tried to run with full_output =1. It's quite possible I haven't done this right. If I have, what else can I do to stop this message from appearing?
> I've attached a quick print-screen of the code.
> Any help is much appreciated.

Others have already said this but I'd like to repeat it: it would be a lot
easier for me to help with something like this if you put your code in the
email.

There are two problems with your code: one physical and one programmatic.

The physical problem is that your initial conditions are actually inside the
planet. Your code assumes that Mars is centred at the (0, 0) point. The radius
of Mars is ~3e6m but your initial condition is at (1000, 1000)m which is very
near the centre of Mars. The gravitational field at that point in Mars is
massive using the formula that you have shown. The large numbers will almost
certainly cause problems with the numerical accuracy of the integrator which
is probably why you see the warning messages.

In reality the gravitational field that close to the centre of Mars will be
very weak because of the shell theorem but your formula assumes a point mass
distribution so it doesn't take account of that:
http://en.wikipedia.org/wiki/Shell_theorem#Inside_a_shell
So the orbits you see there would be unphysical even if it wasn't for the
numerical accuracy problems.

If you change your initial condition to the following then your code will
produce sensible results:

xx0 = [
    4e6, # xpos - m - 1000 km above the surface of Mars along the x-axis
    0,   # xvel - m/s
    0,   # ypos - m
    2000,# yvel - m/s - initial velocity perpendicular to displacement
    ]

The second problem is programmatic. In your code you are treating your state
vector as [xpos, xvel, ypos, yvel] but at the end when you extract the
timeseries for each variable you have instead assumed a different ordering:
[xpos, ypos, xvel, yvel]. You should change the lines at the end to:

xx = soln[:, 0]
vx = soln[:, 1]
xy = soln[:, 2]
vy = soln[:, 3]

With those two changes I think you'll see a nice elliptic orbit.

I would suggest assigning the variable indices to names and then using those
in your code. So for example at the top of your file you could write:

# Variable indices
XPOS, YPOS, XVEL, YVEL = range(4)

Then your derivative function becomes more readable:

def f(x, t):
    r = ((x[XPOS]**2) + (x[YPOS]**2))**0.5
    dxdt = np.zeros_like(x)
    dxdt[XPOS] = x[XVEL]
    dxdt[YPOS] = x[YVEL]
    dxdt[XVEL] = G*Mm * x[XPOS]/r**3
    dxdt[YVEL] = G*Mm * x[YPOS]/r**3
    return dxdt

And at the end you can just write:

xx = soln[:, XPOS]
xy = soln[:, YPOS]
vx = soln[:, XVEL]
vy = soln[:, YVEL]

This way you'll be less likely to make mistakes with the indices.


Oscar

From steve at pearwood.info  Wed Jan 15 12:25:11 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 15 Jan 2014 22:25:11 +1100
Subject: [Tutor] Euler Spoiler
In-Reply-To: <CAGZAPF4D=Ar7+f8xUrCsYLZ0S3901KgEvHv7bscLFDcRGGt-0A@mail.gmail.com>
References: <CAO5ffbYjxh9AcPhTBGUrX5_fxayyikCvP3fG2X-XDxNP4ErppQ@mail.gmail.com>
 <lavfoe$l5$1@ger.gmane.org>
 <CAO5ffbbg24qN0LNLgUXT3JoWXdgDd0jQL1584avud-K+GtRK0Q@mail.gmail.com>
 <CAGZAPF4D=Ar7+f8xUrCsYLZ0S3901KgEvHv7bscLFDcRGGt-0A@mail.gmail.com>
Message-ID: <20140115112511.GQ3869@ando>

On Sun, Jan 12, 2014 at 09:56:09PM -0800, Danny Yoo wrote:

> Here's a sketch of how I'd attack this by considering a DP-style
> approach.  If you want to avoid any spoilers, please skip this
> message.
> 
> Otherwise, I'll try to be as transparent as to my thought process as I can.

[snip]

Nicely done! That was really well written.


-- 
Steven

From oscar.j.benjamin at gmail.com  Wed Jan 15 12:33:58 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Wed, 15 Jan 2014 11:33:58 +0000
Subject: [Tutor] Problems using odeint
In-Reply-To: <20140115000851.GI3869@ando>
References: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
 <20140115000851.GI3869@ando>
Message-ID: <20140115113355.GB4952@gmail.com>

On Wed, Jan 15, 2014 at 11:08:51AM +1100, Steven D'Aprano wrote:
>
> Unfortunately, I don't think there is anyone here who is very familiar
> with scipy.

There's Eryksun and me at least. I think that simple scientific Python
questions get answered round here.

If the science itself or the libraries used are highly specialised then as
with anything highly specialised this may not be the best place to ask. But
when the programming is simple and the science is standard then I think you'll
get a reasonable response here.


Oscar

From steve at pearwood.info  Wed Jan 15 12:37:40 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 15 Jan 2014 22:37:40 +1100
Subject: [Tutor] Problems using odeint
In-Reply-To: <20140115113355.GB4952@gmail.com>
References: <DUB127-W141785E254286C45470E9ED0BF0@phx.gbl>
 <20140115000851.GI3869@ando> <20140115113355.GB4952@gmail.com>
Message-ID: <20140115113740.GR3869@ando>

On Wed, Jan 15, 2014 at 11:33:58AM +0000, Oscar Benjamin wrote:
> On Wed, Jan 15, 2014 at 11:08:51AM +1100, Steven D'Aprano wrote:
> >
> > Unfortunately, I don't think there is anyone here who is very familiar
> > with scipy.
> 
> There's Eryksun and me at least. I think that simple scientific Python
> questions get answered round here.
> 
> If the science itself or the libraries used are highly specialised then as
> with anything highly specialised this may not be the best place to ask. But
> when the programming is simple and the science is standard then I think you'll
> get a reasonable response here.

Fair enough! I will try to remember that the two of you have numpy/scipy 
experience, and apologise in advance for when I forget :-)


-- 
Steven

From kuku at physik.rwth-aachen.de  Wed Jan 15 13:55:53 2014
From: kuku at physik.rwth-aachen.de (Christoph Kukulies)
Date: Wed, 15 Jan 2014 13:55:53 +0100
Subject: [Tutor] iPython notebook In [*]: numbering
In-Reply-To: <CACL+1av25vn9x_k4Tb8xZnDnFfEUV66VM6HheiQ35+cxnmoFfQ@mail.gmail.com>
References: <1389687774536-5043985.post@n6.nabble.com>
 <CACL+1av25vn9x_k4Tb8xZnDnFfEUV66VM6HheiQ35+cxnmoFfQ@mail.gmail.com>
Message-ID: <52D68559.1090807@physik.rwth-aachen.de>

Am 14.01.2014 15:27, schrieb eryksun:
> On Tue, Jan 14, 2014 at 3:22 AM, Krischu <kukulies at physik.rwth-aachen.de> wrote:
>> When I started I had In [0]:, In[1] etc.
>>
>> Now the notebook starts with In [2]:, In [3]: then In [9]:
>>
>> Yesterday before storing and leaving the notebook I suddenly had all In[]'s
>> marked like In [*]:
>>
>> Is there a method behind this? Can one reorder/garbage collect the notebook?
> Did you try restarting the kernel and then recalculating the cells?
>
>      Kernel => Restart
>        Cell => Run All

Thanks. These both in that order helped to fix it.

--
Christoph


From steve at pearwood.info  Wed Jan 15 22:55:41 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 16 Jan 2014 08:55:41 +1100
Subject: [Tutor] iPython notebook In [*]: numbering
In-Reply-To: <52D68559.1090807@physik.rwth-aachen.de>
References: <1389687774536-5043985.post@n6.nabble.com>
 <CACL+1av25vn9x_k4Tb8xZnDnFfEUV66VM6HheiQ35+cxnmoFfQ@mail.gmail.com>
 <52D68559.1090807@physik.rwth-aachen.de>
Message-ID: <20140115215541.GT3869@ando>

On Wed, Jan 15, 2014 at 01:55:53PM +0100, Christoph Kukulies wrote:
> Am 14.01.2014 15:27, schrieb eryksun:
> >On Tue, Jan 14, 2014 at 3:22 AM, Krischu <kukulies at physik.rwth-aachen.de> 
> >wrote:
> >>When I started I had In [0]:, In[1] etc.
> >>
> >>Now the notebook starts with In [2]:, In [3]: then In [9]:
> >>
> >>Yesterday before storing and leaving the notebook I suddenly had all 
> >>In[]'s marked like In [*]:
> >>
> >>Is there a method behind this? Can one reorder/garbage collect the 
> >>notebook?
> >
> >Did you try restarting the kernel and then recalculating the cells?
> >
> >     Kernel => Restart
> >       Cell => Run All
> 
> Thanks. These both in that order helped to fix it.


I'm glad that Eryksun was able to help, now would somebody like to 
explain what was going on?

I don't even understand the answer given. I tried entering "Kernel => 
Restart" at the iPython prompt, and got a SyntaxError.

In [1]: Kernel => Restart
------------------------------------------------------------
   File "<ipython console>", line 1
     Kernel => Restart
             ^
SyntaxError: invalid syntax



-- 
Steven

From eryksun at gmail.com  Wed Jan 15 23:10:10 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 15 Jan 2014 17:10:10 -0500
Subject: [Tutor] iPython notebook In [*]: numbering
In-Reply-To: <20140115215541.GT3869@ando>
References: <1389687774536-5043985.post@n6.nabble.com>
 <CACL+1av25vn9x_k4Tb8xZnDnFfEUV66VM6HheiQ35+cxnmoFfQ@mail.gmail.com>
 <52D68559.1090807@physik.rwth-aachen.de> <20140115215541.GT3869@ando>
Message-ID: <CACL+1asL=cyuCu5ArmkAXE1+XnfH-6XZ3Q8D2wH5Ec2P3QeFLA@mail.gmail.com>

On Wed, Jan 15, 2014 at 4:55 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Wed, Jan 15, 2014 at 01:55:53PM +0100, Christoph Kukulies wrote:
>> Am 14.01.2014 15:27, schrieb eryksun:
>> >Did you try restarting the kernel and then recalculating the cells?
>> >
>> >     Kernel => Restart
>> >       Cell => Run All
>>
>> Thanks. These both in that order helped to fix it.
>
>
> I'm glad that Eryksun was able to help, now would somebody like to
> explain what was going on?
>
> I don't even understand the answer given. I tried entering "Kernel =>
> Restart" at the iPython prompt, and got a SyntaxError.

The question is about using an IPython notebook (it's similar to a
Mathematica notebook):

http://ipython.org/notebook.html

I assumed familiarity with the "Kernel" and "Cell" menus.

From oscar.j.benjamin at gmail.com  Thu Jan 16 00:59:37 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Wed, 15 Jan 2014 23:59:37 +0000
Subject: [Tutor] iPython notebook In [*]: numbering
In-Reply-To: <20140115215541.GT3869@ando>
References: <1389687774536-5043985.post@n6.nabble.com>
 <CACL+1av25vn9x_k4Tb8xZnDnFfEUV66VM6HheiQ35+cxnmoFfQ@mail.gmail.com>
 <52D68559.1090807@physik.rwth-aachen.de> <20140115215541.GT3869@ando>
Message-ID: <CAHVvXxTwRDSsM91Mc2mfJTGS6kVEPs9oanpYM34=H5mCcXKw-Q@mail.gmail.com>

On 15 January 2014 21:55, Steven D'Aprano <steve at pearwood.info> wrote:
> I'm glad that Eryksun was able to help, now would somebody like to
> explain what was going on?
>
> I don't even understand the answer given. I tried entering "Kernel =>
> Restart" at the iPython prompt, and got a SyntaxError.

IPython notebooks allow the IPython terminal to be used from a browser
in combination with graphical components that wouldn't work in a
terminal such as plots (matplotlib) and equations (sympy).

See e.g. here for examples of how it looks with sympy (notice that the
sympy output is rendered as proper equations with Mathjax in the
browser).
http://nbviewer.ipython.org/github/ipython/ipython/blob/master/examples/notebooks/SymPy%20Examples.ipynb


Oscar

From denis.spir at gmail.com  Thu Jan 16 11:31:10 2014
From: denis.spir at gmail.com (spir)
Date: Thu, 16 Jan 2014 11:31:10 +0100
Subject: [Tutor] lambdas, generators, and the like
In-Reply-To: <CAO5ffbbNRmgd0WZFYC3pMNS1+KbYGBz4dJkZR-gDvHvSq0S3_w@mail.gmail.com>
References: <CAO5ffbZAWhwYCdqKo==0SDX0y1_E6w8M90N0v111dGzV7G6uyw@mail.gmail.com>
 <lau8vm$no0$1@ger.gmane.org>
 <CAO5ffbbNRmgd0WZFYC3pMNS1+KbYGBz4dJkZR-gDvHvSq0S3_w@mail.gmail.com>
Message-ID: <52D7B4EE.4030508@gmail.com>

On 01/12/2014 07:40 PM, Keith Winston wrote:
> Thanks Dave, that looks like a good idea, I've played a little with
> one-line generators (? the things similar to list comprehensions), but
> I'm still wrapping my head around how to use them.

You probably mean a generator *expression*. it's written like a list 
comprehension, bit with () instead of []. The semantic difference is that items 
are generated once at a time instead of all in one go and stored in a list. 
Another difference is that one cannot reuse such a generator object (once end is 
reached, it is like "empty").

spir at ospir:~$ python3
Python 3.3.1 (default, Sep 25 2013, 19:29:01)
[GCC 4.7.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> l = [1,2,3]
>>> squares = [n*n for n in l]
>>> squares
[1, 4, 9]
>>> for (i,sq) in enumerate(squares):
...     print(i+1, sq)
...
1 1
2 4
3 9
>>> squares = (n*n for n in l)
>>> squares
<generator object <genexpr> at 0x7f92496a7be0>
>>> for (i,sq) in enumerate(squares):
...     print(i+1, sq)
...
1 1
2 4
3 9
>>>

From denis.spir at gmail.com  Thu Jan 16 11:44:01 2014
From: denis.spir at gmail.com (spir)
Date: Thu, 16 Jan 2014 11:44:01 +0100
Subject: [Tutor] lambdas, generators, and the like
In-Reply-To: <CAO5ffbZAWhwYCdqKo==0SDX0y1_E6w8M90N0v111dGzV7G6uyw@mail.gmail.com>
References: <CAO5ffbZAWhwYCdqKo==0SDX0y1_E6w8M90N0v111dGzV7G6uyw@mail.gmail.com>
Message-ID: <52D7B7F1.6010601@gmail.com>

On 01/12/2014 10:04 AM, Keith Winston wrote:
> I've got this line:
>
> for k in range(len(tcombo)):
>      tcombo_ep.append(list(combinations(tcombo, k+1)))
>
> generating every possible length combination of tcombo. I then test
> them, and throw most of them away. I need to do this differently, it
> gets way too big (crashes my computer).
>
> I'm going to play some more, but I think I need to test the
> combinations as they're generated... and then only add them to a list
> (probably better: a set) if they meet a requirement (something like
> sum(specific.combination(tcombo) == goal)) AND if they are not already
> part of that list (the uniqueness issue is why a set might be better)
>
> I'm partially asking in order to clarify the question in my mind, but
> any help will be appreciated. I don't really understand lambda
> functions yet, but I can sort of imagine they might work here
> somehow... or not.

You say yourself that, on the application side, the semantics are that relevant 
items (individual combinations) are a subset of the ones otherwise produced, 
right? Thus they are conceptually the output of a *filter*. Whether they are 
stored (in a list --> list comprehension) or directly processed (from a 
generator --> generator expression), you should only ever deal with the relevant 
ones.

       production                filter
data     --->     combinations   --->   [storage] usage

If the filter's criterion is 'crit':
	combs = (comb for comb in combinations(tcombo, k+1)) if crit(comb))

This, in addition to the requirement of uniqueness which as you say is probably 
best met using a set (after filter). This may lead to you chosing to store, even 
if otherwise not truely necessary. An question is: what kind of data are 
combinations, and how do you compare them? If there is a possibly cheap shortcut 
by comparing only a little bit of combination data, then you may make a set of 
those little bits only and avoid storing the whole of combinations.

Denis

From james at uplinkzero.com  Thu Jan 16 11:32:02 2014
From: james at uplinkzero.com (James Chapman)
Date: Thu, 16 Jan 2014 10:32:02 +0000
Subject: [Tutor] Mocking with "mock" in unit testing
Message-ID: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>

Hi all

I have a question regarding mocking in unit testing.

Let's assume I have the following class:

-------------------------------------------
import subprocess

class Pinger(object):

    def ping_host(self, host_to_ping):
        cmd_string = 'ping %s' % (host_to_ping)
        cmd_args = cmd_string.split()
        proc = subprocess.Popen(cmd_args, shell=True)
        proc.wait()
        if proc.returncode != 1:
            raise Exception('Error code was: %d' % (proc.returncode))

-------------------------------------------


In my unittest I don't want to run the ping command, (It might not be
available on the build system) I merely want to check that a call to
subprocess.Popen is made and that the parameters are what I expect?

So far I have this, but it doesn't work and I suspect it's way off!!


-------------------------------------------
import mock
import unittest
from tutor_q import Pinger

class Test_Pinger(unittest.TestCase):

    def test_ping_host(self):
        pinger = Pinger()
        assert pinger
        subprocess = mock.Mock()
        subprocess.Popen.return_value = 0
        subprocess.assert_called_once_with(['ping','localhost'])
        pinger.ping_host('127.0.0.1')




if __name__ == '__main__':
    unittest.main()

-------------------------------------------


Can anyone point me in the right direction on how to mock up these
subprocess calls?

Thanks

James
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140116/69345d21/attachment.html>

From eryksun at gmail.com  Fri Jan 17 02:05:10 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 16 Jan 2014 20:05:10 -0500
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
Message-ID: <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>

On Thu, Jan 16, 2014 at 5:32 AM, James Chapman <james at uplinkzero.com> wrote:
>
> In my unittest I don't want to run the ping command, (It might not be
> available on the build system) I merely want to check that a call to
> subprocess.Popen is made and that the parameters are what I expect?

You can mock `Popen` where it's accessed.

    @mock.patch('subprocess.Popen')
    def test_ping_host(self, Popen):
        Popen.return_value.returncode = 0
        pinger = Pinger()
        pinger.ping_host('127.0.0.1')
        Popen.assert_called_once_with(['ping','127.0.0.1'], shell=True)

If the tutor_q module imported `Popen` into its namespace, then you'd
patch tutor_q.Popen.

>     def ping_host(self, host_to_ping):
>         cmd_string = 'ping %s' % (host_to_ping)
>         cmd_args = cmd_string.split()

Splitting on spaces doesn't work generally. Use `shlex.split`, or
build the list manually.

>         proc = subprocess.Popen(cmd_args, shell=True)

Maybe you really need the shell to process your command, but generally
there's no reason to run the shell just to have it execute the command
and wait. Plus it opens the door to security exploits.

>         proc.wait()
>         if proc.returncode != 1:
>             raise Exception('Error code was: %d' % (proc.returncode))

A non-zero return code signals an error. When using `Popen` directly,
you can be consistent with `check_call` and `check_output` if you
raise a `CalledProcessError` in this case:

    retcode = proc.wait()
    if retcode:
        raise subprocess.CalledProcessError(retcode, cmd_args)

From keithwins at gmail.com  Fri Jan 17 06:54:59 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 17 Jan 2014 00:54:59 -0500
Subject: [Tutor] Tutor Digest, Vol 115, Issue 28
In-Reply-To: <20140115111215.GP3869@ando>
References: <mailman.2095.1379016934.5460.tutor@python.org>
 <CAKSTmRDWd0rZrp-rTUmzzVLyFH1D4ZPb+4G4__o+LAWp0psvYQ@mail.gmail.com>
 <laso3c$qc3$1@ger.gmane.org>
 <CAO5ffbbHdpHDZuOcs5z-5T+BQFMTkM+Tq8wAG7b97RJ_UC17sQ@mail.gmail.com>
 <20140115111215.GP3869@ando>
Message-ID: <CAO5ffbZuJxydCOJTLZu_cj5c5us_Hj-LeBtQnwFxuAQQa1ZPrA@mail.gmail.com>

On Wed, Jan 15, 2014 at 6:12 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> You're selling youself short. From what I've seen of you on this list,
> you might be a beginner, but you've got the right sort of inquiring mind
> to go far as a programmer.

Thanks Steven, I've abruptly gotten clear how much work I have ahead
of me, but that's fine, I'll get as far as I get as fast as I get
there... Reading your modules is really quite informative, btw, your
commenting is both helpful and exemplary, it's already started
changing the way I program, vastly for the better. I always thought I
liked end-of-line comments, so I can see program flow without
comments, but inline commenting can be done in a way to vastly enhance
readability, I see now. Anyway, I'm playing with the Google examples a
bit right now, just to get more practice. I'm hoping to try something
a little bigger soon.

-- 
Keith

From keithwins at gmail.com  Fri Jan 17 07:06:19 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 17 Jan 2014 01:06:19 -0500
Subject: [Tutor] lambdas, generators, and the like
In-Reply-To: <52D7B7F1.6010601@gmail.com>
References: <CAO5ffbZAWhwYCdqKo==0SDX0y1_E6w8M90N0v111dGzV7G6uyw@mail.gmail.com>
 <52D7B7F1.6010601@gmail.com>
Message-ID: <CAO5ffbZN6Fq4bphuQUnstzNY=BcpOC0kxFdy2VCKfg4utTu4PA@mail.gmail.com>

On Thu, Jan 16, 2014 at 5:44 AM, spir <denis.spir at gmail.com> wrote:
> This, in addition to the requirement of uniqueness which as you say is
> probably best met using a set (after filter). This may lead to you chosing
> to store, even if otherwise not truely necessary. An question is: what kind
> of data are combinations, and how do you compare them? If there is a
> possibly cheap shortcut by comparing only a little bit of combination data,
> then you may make a set of those little bits only and avoid storing the
> whole of combinations.


Hmmm. My guess is you're reaching for a teachable moment here... I
ended up leaving this entire approach behind, for what I think is your
point: I can simply iterate through the combinations and test them
before I even get to the next one. Sadly, this didn't nearly address
my problem, which I think is that my solution set is still ending up
N^2 time on a rather large data set. Danny offered a different
approach entirely, which I haven't implemented. I THINK that I
optimized this approach by not using any lists, testing iterations as
they were generated, changing my data order so I generate shorter
combinations first, and I STILL couldn't get past something like the
first 3 coins out of 8. It's all good, I learned a lot in the process.

-- 
Keith

From james at uplinkzero.com  Fri Jan 17 10:58:06 2014
From: james at uplinkzero.com (James Chapman)
Date: Fri, 17 Jan 2014 09:58:06 +0000
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
Message-ID: <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>

Thanks eryksun.

There's a list for testing in python which I also posed the question to and
got pretty much the same answer as you provided.

The line if proc.returncode != 1 was a mistake. That 1 should have been a
zero.

As this question was just about mock and not really dealing with the bad
return code or exception handling or raising my final working example looks
like this:


pinger.py

----------------------------

import subprocess
 class Pinger(object):

    def ping_host(self, host_to_ping):
        cmd_string = 'ping %s' % (host_to_ping)
        cmd_args = cmd_string.split()
        proc = subprocess.Popen(cmd_args, shell=True)
        proc.wait()
        if proc.returncode != 0:
            raise Exception('Error code was: %d' % (proc.returncode))

 if __name__ == '__main__':
    PINGER = Pinger()
    PINGER.ping_host('localhost')

----------------------------



test_pinger.py

----------------------------

import mockimport unittestimport pinger
 class Test_Pinger(unittest.TestCase):

    def test_ping_host_succeeds(self):
        pinger = pinger.Pinger()
        with mock.patch("pinger.subprocess") as subprocess:
            subprocess.Popen.return_value.returncode = 0
            pinger.ping_host('localhost')
            subprocess.Popen.assert_called_once_with(['ping','localhost'],
shell=True)

    def test_ping_host_fails_and_throws_exception(self):
        pinger = pinger.Pinger()
        with mock.patch('pinger.subprocess') as subprocess:
            subprocess.Popen.return_value.returncode = 1
            self.assertRaises(Exception, pinger.ping_host, 'localhost')

 if __name__ == '__main__':
    unittest.main()

----------------------------




--
James


On 17 January 2014 01:05, eryksun <eryksun at gmail.com> wrote:

> On Thu, Jan 16, 2014 at 5:32 AM, James Chapman <james at uplinkzero.com>
> wrote:
> >
> > In my unittest I don't want to run the ping command, (It might not be
> > available on the build system) I merely want to check that a call to
> > subprocess.Popen is made and that the parameters are what I expect?
>
> You can mock `Popen` where it's accessed.
>
>     @mock.patch('subprocess.Popen')
>     def test_ping_host(self, Popen):
>         Popen.return_value.returncode = 0
>         pinger = Pinger()
>         pinger.ping_host('127.0.0.1')
>         Popen.assert_called_once_with(['ping','127.0.0.1'], shell=True)
>
> If the tutor_q module imported `Popen` into its namespace, then you'd
> patch tutor_q.Popen.
>
> >     def ping_host(self, host_to_ping):
> >         cmd_string = 'ping %s' % (host_to_ping)
> >         cmd_args = cmd_string.split()
>
> Splitting on spaces doesn't work generally. Use `shlex.split`, or
> build the list manually.
>
> >         proc = subprocess.Popen(cmd_args, shell=True)
>
> Maybe you really need the shell to process your command, but generally
> there's no reason to run the shell just to have it execute the command
> and wait. Plus it opens the door to security exploits.
>
> >         proc.wait()
> >         if proc.returncode != 1:
> >             raise Exception('Error code was: %d' % (proc.returncode))
>
> A non-zero return code signals an error. When using `Popen` directly,
> you can be consistent with `check_call` and `check_output` if you
> raise a `CalledProcessError` in this case:
>
>     retcode = proc.wait()
>     if retcode:
>         raise subprocess.CalledProcessError(retcode, cmd_args)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140117/bc5b3ec2/attachment-0001.html>

From eryksun at gmail.com  Fri Jan 17 11:50:39 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 17 Jan 2014 05:50:39 -0500
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
Message-ID: <CACL+1asr_7ccuV0Wcqb9WNP0rscLpSE1UVEj=Ly4pdwd2xjEhA@mail.gmail.com>

On Fri, Jan 17, 2014 at 4:58 AM, James Chapman <james at uplinkzero.com> wrote:
> import mock
> import unittest
> import pinger
>
> class Test_Pinger(unittest.TestCase):
>
>     def test_ping_host_succeeds(self):
>         pinger = pinger.Pinger()

Are you using CPython? That raises an UnboundLocalError. Take a look
at the CPython bytecode:

    def test(self):
        pinger = pinger.Pinger()

    >>> dis.dis(test)
      2           0 LOAD_FAST                1 (pinger)
                  3 LOAD_ATTR                0 (Pinger)
                  6 CALL_FUNCTION            0
                  9 STORE_FAST               1 (pinger)
                 12 LOAD_CONST               0 (None)
                 15 RETURN_VALUE

Notice LOAD_FAST(1), where fast local 1 is the local variable
`pinger`. The value isn't assigned yet, and LOAD_FAST doesn't search
globals and builtins. You need a unique name for the instance, such as
`test_pinger`. Then the compiler knows to use LOAD_GLOBAL:

    def test(self):
        test_pinger = pinger.Pinger()

    >>> dis.dis(test)
      2           0 LOAD_GLOBAL              0 (pinger)
                  3 LOAD_ATTR                1 (Pinger)
                  6 CALL_FUNCTION            0
                  9 STORE_FAST               1 (test_pinger)
                 12 LOAD_CONST               0 (None)
                 15 RETURN_VALUE

Here's a version using a decorator instead:

    @mock.patch('pinger.subprocess')
    def test_ping_host_succeeds(self, subprocess):
        subprocess.Popen.return_value.returncode = 0
        test_pinger = pinger.Pinger()
        test_pinger.ping_host('localhost')
        subprocess.Popen.assert_called_once_with(['ping','localhost'],
                                                 shell=True)

From steve at pearwood.info  Fri Jan 17 12:23:37 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 17 Jan 2014 22:23:37 +1100
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
Message-ID: <20140117112337.GH3915@ando>

On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote:

> As this question was just about mock and not really dealing with the bad
> return code or exception handling or raising my final working example looks
> like this:

Your final *working* example? I don't think so. I can see at least two 
syntax errors, and a programming error.

A word to the wise: code isn't working until you've actually seen it 
work :-)



> pinger.py
> 
> ----------------------------
> 
> import subprocess
>  class Pinger(object):

There is your first SyntaxError, a stray space ahead of the "class" 
keyword.


>     def ping_host(self, host_to_ping):
>         cmd_string = 'ping %s' % (host_to_ping)
>         cmd_args = cmd_string.split()

This is not a programming error, but it is wasteful. First you join two 
strings: "ping", and the host. Then, having glued them together, you 
split them apart exactly where you glued them.

Better to do something like: 

        cmd_args = ["ping", host_to_ping]

assuming that you know that host_to_ping is only a single word.


>         proc = subprocess.Popen(cmd_args, shell=True)

Why shell=True?

The documentation for subprocess.Popen says:

    The shell argument (which defaults to False) specifies whether to 
    use the shell as the program to execute. If shell is True, it is
    recommended to pass args as a string rather than as a sequence.

and also warns that shell=True can be a security hazard. Do you have a 
good reason for using it?

http://docs.python.org/2/library/subprocess.html



>         proc.wait()
>         if proc.returncode != 0:
>             raise Exception('Error code was: %d' % (proc.returncode))
> 
>  if __name__ == '__main__':
>     PINGER = Pinger()
>     PINGER.ping_host('localhost')
> 
> ----------------------------
> 
> 
> 
> test_pinger.py
> 
> ----------------------------
> 
> import mockimport unittestimport pinger
>  class Test_Pinger(unittest.TestCase):

And here you have two more SyntaxErrors: missing commas between 
arguments to import, and a stray space before the "class" again.


>     def test_ping_host_succeeds(self):
>         pinger = pinger.Pinger()

And here is your programming error. Unlike some programming languages 
(Lua, I think) in Python you cannot use the same name to refer to both a 
global variable and a local variable inside the same function. In 
Python, either the variable is treated as a global, or as a local, but 
not both.

The rules Python uses to decide are:

* if you declare a name "global" inside the function, then it is 
  treated as global inside that function;

* otherwise, if you assign a value to the name *anywhere* inside 
  the function, it is treated as local;

* otherwise it is global.

So in your example, you assign a value to the name "pinger", so it is 
treated as local. The offending line of code looks like this:

    pinger = pinger.Pinger()

Your *intention* is to look up the global "pinger", which is a module, 
then create a pinger.Pinger() instance, then assign it to the local 
variable "pinger". But that's not what Python does. Instead, it tries to 
look up a local variable "pinger", finds it doesn't have one, and raises 
an UnboundLocalError exception.

I recommend you change the name of the local variable "pinger" to 
something else, so it no longer clashes with the "pinger" module name.


Hope this is of help to you,



-- 
Steven

From james at uplinkzero.com  Fri Jan 17 12:18:48 2014
From: james at uplinkzero.com (James Chapman)
Date: Fri, 17 Jan 2014 11:18:48 +0000
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <CACL+1asr_7ccuV0Wcqb9WNP0rscLpSE1UVEj=Ly4pdwd2xjEhA@mail.gmail.com>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
 <CACL+1asr_7ccuV0Wcqb9WNP0rscLpSE1UVEj=Ly4pdwd2xjEhA@mail.gmail.com>
Message-ID: <CAHvkzyk_X1ssVo+PKibr0RWuDio+sXWa+3_Ntsni9tjo-aD7UA@mail.gmail.com>

Erm...?

CPython yeah.

If I rename "pinger.py" to "tutor.py" and change the unittest it runs fine.
Why?


-------------------------
import mock
import unittest
import tutor

class Test_Pinger(unittest.TestCase):

    def test_ping_host_succeeds(self):
        pinger = tutor.Pinger()
        with mock.patch("tutor.subprocess") as subprocess:
            subprocess.Popen.return_value.returncode = 0
            pinger.ping_host('localhost')
            subprocess.Popen.assert_called_once_with(['ping','localhost'],
shell=True)


    def test_ping_host_fails_and_throws_exception(self):
        pinger = tutor.Pinger()
        with mock.patch('tutor.subprocess') as subprocess:
            subprocess.Popen.return_value.returncode = 1
            self.assertRaises(Exception, pinger.ping_host, 'localhost')



if __name__ == '__main__':
    unittest.main()
-------------------------


--
James


On 17 January 2014 10:50, eryksun <eryksun at gmail.com> wrote:

> On Fri, Jan 17, 2014 at 4:58 AM, James Chapman <james at uplinkzero.com>
> wrote:
> > import mock
> > import unittest
> > import pinger
> >
> > class Test_Pinger(unittest.TestCase):
> >
> >     def test_ping_host_succeeds(self):
> >         pinger = pinger.Pinger()
>
> Are you using CPython? That raises an UnboundLocalError. Take a look
> at the CPython bytecode:
>
>     def test(self):
>         pinger = pinger.Pinger()
>
>     >>> dis.dis(test)
>       2           0 LOAD_FAST                1 (pinger)
>                   3 LOAD_ATTR                0 (Pinger)
>                   6 CALL_FUNCTION            0
>                   9 STORE_FAST               1 (pinger)
>                  12 LOAD_CONST               0 (None)
>                  15 RETURN_VALUE
>
> Notice LOAD_FAST(1), where fast local 1 is the local variable
> `pinger`. The value isn't assigned yet, and LOAD_FAST doesn't search
> globals and builtins. You need a unique name for the instance, such as
> `test_pinger`. Then the compiler knows to use LOAD_GLOBAL:
>
>     def test(self):
>         test_pinger = pinger.Pinger()
>
>     >>> dis.dis(test)
>       2           0 LOAD_GLOBAL              0 (pinger)
>                   3 LOAD_ATTR                1 (Pinger)
>                   6 CALL_FUNCTION            0
>                   9 STORE_FAST               1 (test_pinger)
>                  12 LOAD_CONST               0 (None)
>                  15 RETURN_VALUE
>
> Here's a version using a decorator instead:
>
>     @mock.patch('pinger.subprocess')
>     def test_ping_host_succeeds(self, subprocess):
>         subprocess.Popen.return_value.returncode = 0
>         test_pinger = pinger.Pinger()
>         test_pinger.ping_host('localhost')
>         subprocess.Popen.assert_called_once_with(['ping','localhost'],
>                                                  shell=True)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140117/1603996d/attachment.html>

From james at uplinkzero.com  Fri Jan 17 12:39:06 2014
From: james at uplinkzero.com (James Chapman)
Date: Fri, 17 Jan 2014 11:39:06 +0000
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <20140117112337.GH3915@ando>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
 <20140117112337.GH3915@ando>
Message-ID: <CAHvkzy=aCzb1Rv4LZE=0EC943YEGFsopprvXDeX5GdNLpL0uYA@mail.gmail.com>

Ah of course!
pinger = pinger.Pinger() .... I should have noticed that myself.  (I
renamed the file to pinger.py after establishing it all worked and then
didn't re-run).
ping = pinger.Pinger() works fine.

As for the syntax errors, those will be copy paste / different email client
errors.

--
James


On 17 January 2014 11:23, Steven D'Aprano <steve at pearwood.info> wrote:

> On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote:
>
> > As this question was just about mock and not really dealing with the bad
> > return code or exception handling or raising my final working example
> looks
> > like this:
>
> Your final *working* example? I don't think so. I can see at least two
> syntax errors, and a programming error.
>
> A word to the wise: code isn't working until you've actually seen it
> work :-)
>
>
>
> > pinger.py
> >
> > ----------------------------
> >
> > import subprocess
> >  class Pinger(object):
>
> There is your first SyntaxError, a stray space ahead of the "class"
> keyword.
>
>
> >     def ping_host(self, host_to_ping):
> >         cmd_string = 'ping %s' % (host_to_ping)
> >         cmd_args = cmd_string.split()
>
> This is not a programming error, but it is wasteful. First you join two
> strings: "ping", and the host. Then, having glued them together, you
> split them apart exactly where you glued them.
>
> Better to do something like:
>
>         cmd_args = ["ping", host_to_ping]
>
> assuming that you know that host_to_ping is only a single word.
>
>
> >         proc = subprocess.Popen(cmd_args, shell=True)
>
> Why shell=True?
>
> The documentation for subprocess.Popen says:
>
>     The shell argument (which defaults to False) specifies whether to
>     use the shell as the program to execute. If shell is True, it is
>     recommended to pass args as a string rather than as a sequence.
>
> and also warns that shell=True can be a security hazard. Do you have a
> good reason for using it?
>
> http://docs.python.org/2/library/subprocess.html
>
>
>
> >         proc.wait()
> >         if proc.returncode != 0:
> >             raise Exception('Error code was: %d' % (proc.returncode))
> >
> >  if __name__ == '__main__':
> >     PINGER = Pinger()
> >     PINGER.ping_host('localhost')
> >
> > ----------------------------
> >
> >
> >
> > test_pinger.py
> >
> > ----------------------------
> >
> > import mockimport unittestimport pinger
> >  class Test_Pinger(unittest.TestCase):
>
> And here you have two more SyntaxErrors: missing commas between
> arguments to import, and a stray space before the "class" again.
>
>
> >     def test_ping_host_succeeds(self):
> >         pinger = pinger.Pinger()
>
> And here is your programming error. Unlike some programming languages
> (Lua, I think) in Python you cannot use the same name to refer to both a
> global variable and a local variable inside the same function. In
> Python, either the variable is treated as a global, or as a local, but
> not both.
>
> The rules Python uses to decide are:
>
> * if you declare a name "global" inside the function, then it is
>   treated as global inside that function;
>
> * otherwise, if you assign a value to the name *anywhere* inside
>   the function, it is treated as local;
>
> * otherwise it is global.
>
> So in your example, you assign a value to the name "pinger", so it is
> treated as local. The offending line of code looks like this:
>
>     pinger = pinger.Pinger()
>
> Your *intention* is to look up the global "pinger", which is a module,
> then create a pinger.Pinger() instance, then assign it to the local
> variable "pinger". But that's not what Python does. Instead, it tries to
> look up a local variable "pinger", finds it doesn't have one, and raises
> an UnboundLocalError exception.
>
> I recommend you change the name of the local variable "pinger" to
> something else, so it no longer clashes with the "pinger" module name.
>
>
> Hope this is of help to you,
>
>
>
> --
> Steven
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140117/8561f715/attachment-0001.html>

From eryksun at gmail.com  Fri Jan 17 14:35:04 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 17 Jan 2014 08:35:04 -0500
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <20140117112337.GH3915@ando>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
 <20140117112337.GH3915@ando>
Message-ID: <CACL+1avVwuCT3j=O_k26r7r91qA-ev10pJfgw+SeDf+b99rUBw@mail.gmail.com>

On Fri, Jan 17, 2014 at 6:23 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote:
>
>> import subprocess
>>  class Pinger(object):
>
> There is your first SyntaxError, a stray space ahead of the "class"
> keyword.

The rich text version is correct (and colorful), but a non-breaking
space ended up on a line in between the <span> elements in the <pre>
block:

    <span s=
    tyle=3D"color:rgb(220,20,60)">subprocess</span>
    =C2=A0
    <span style=3D"color:rgb(255,119,0);font-weight:bold">class</span>

The automated conversion to plain text removed the line break.


> Better to do something like:
>
>         cmd_args = ["ping", host_to_ping]
>
> assuming that you know that host_to_ping is only a single word.

If it isn't a single word, then use `shlex.split`, as I previously suggested.


> Why shell=True?
....
> and also warns that shell=True can be a security hazard. Do you have a
> good reason for using it?

I already asked this and got the response "this question was just about mock".


>> import mockimport unittestimport pinger
>>  class Test_Pinger(unittest.TestCase):
>
> And here you have two more SyntaxErrors: missing commas between
> arguments to import, and a stray space before the "class" again.

This is also fine in the rich text version. BTW, the botched plain
text conversion is missing line breaks, not commas.


>>     def test_ping_host_succeeds(self):
>>         pinger = pinger.Pinger()
>
> And here is your programming error. Unlike some programming languages
> (Lua, I think) in Python you cannot use the same name to refer to both a
> global variable and a local variable inside the same function. In
> Python, either the variable is treated as a global, or as a local, but
> not both.

As you say, for a function. Optimized code requires the name to be
bound locally, else it raises UnboundLocalError. The unoptimized code
of a class body, on the other hand, can load a name from globals or
builtins and then store the same name to locals.

    >>> x = 'global x'
    >>> class C(object):
    ...     x = x + ", but now local"
    ...     print x
    ...
    global x, but now local
    >>> x
    'global x'

From steve at pearwood.info  Fri Jan 17 16:32:34 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 18 Jan 2014 02:32:34 +1100
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <CACL+1avVwuCT3j=O_k26r7r91qA-ev10pJfgw+SeDf+b99rUBw@mail.gmail.com>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
 <20140117112337.GH3915@ando>
 <CACL+1avVwuCT3j=O_k26r7r91qA-ev10pJfgw+SeDf+b99rUBw@mail.gmail.com>
Message-ID: <20140117153233.GI3915@ando>

On Fri, Jan 17, 2014 at 08:35:04AM -0500, eryksun wrote:
> On Fri, Jan 17, 2014 at 6:23 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> > On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote:
[...]
> >> import mockimport unittestimport pinger
> >>  class Test_Pinger(unittest.TestCase):
> >
> > And here you have two more SyntaxErrors: missing commas between
> > arguments to import, and a stray space before the "class" again.
> 
> This is also fine in the rich text version. BTW, the botched plain
> text conversion is missing line breaks, not commas.

I don't understand this. If I'm interpreting you correctly,


import mockimport 
unittestimport 
pinger


would not be "fine".


-- 
Steven

From james at uplinkzero.com  Fri Jan 17 16:43:58 2014
From: james at uplinkzero.com (James Chapman)
Date: Fri, 17 Jan 2014 15:43:58 +0000
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <20140117153233.GI3915@ando>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
 <20140117112337.GH3915@ando>
 <CACL+1avVwuCT3j=O_k26r7r91qA-ev10pJfgw+SeDf+b99rUBw@mail.gmail.com>
 <20140117153233.GI3915@ando>
Message-ID: <CAHvkzykPnGq98=vNJyo+ZRCzBAXaE+ZjRPr_a1hJt3XPRB2Byw@mail.gmail.com>

Really!

import mock
import unittest
import pinger

It should be three lines, but somehow it got all messed up, either
through rich text formatting or copy paste.

Being a bit pedantic now about import statements which are clearly
unintentionally messed up.

- Sent in plain text.



--
James




On 17 January 2014 15:32, Steven D'Aprano <steve at pearwood.info> wrote:
>
> On Fri, Jan 17, 2014 at 08:35:04AM -0500, eryksun wrote:
> > On Fri, Jan 17, 2014 at 6:23 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> > > On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote:
> [...]
> > >> import mockimport unittestimport pinger
> > >>  class Test_Pinger(unittest.TestCase):
> > >
> > > And here you have two more SyntaxErrors: missing commas between
> > > arguments to import, and a stray space before the "class" again.
> >
> > This is also fine in the rich text version. BTW, the botched plain
> > text conversion is missing line breaks, not commas.
>
> I don't understand this. If I'm interpreting you correctly,
>
>
> import mockimport
> unittestimport
> pinger
>
>
> would not be "fine".
>
>
> --
> Steven
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From davea at davea.name  Fri Jan 17 17:05:24 2014
From: davea at davea.name (Dave Angel)
Date: Fri, 17 Jan 2014 11:05:24 -0500 (EST)
Subject: [Tutor] Mocking with "mock" in unit testing
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
 <20140117112337.GH3915@ando>
 <CACL+1avVwuCT3j=O_k26r7r91qA-ev10pJfgw+SeDf+b99rUBw@mail.gmail.com>
 <20140117153233.GI3915@ando>
Message-ID: <lbbk7e$b1s$1@ger.gmane.org>

 Steven D'Aprano <steve at pearwood.info> Wrote in message:
> On Fri, Jan 17, 2014 at 08:35:04AM -0500, eryksun wrote:
>> On Fri, Jan 17, 2014 at 6:23 AM, Steven D'Aprano <steve at pearwood.info> wrote:
>> > On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote:
> [...]
>> >> import mockimport unittestimport pinger
>> >>  class Test_Pinger(unittest.TestCase):
>> >
>> > And here you have two more SyntaxErrors: missing commas between
>> > arguments to import, and a stray space before the "class" again.
>> 
>> This is also fine in the rich text version. BTW, the botched plain
>> text conversion is missing line breaks, not commas.
> 
> I don't understand this. If I'm interpreting you correctly,
> 
> 
> import mockimport 
> unittestimport 
> pinger
> 
> 
> would not be "fine".
> 
> 
You're putting the linefeeds in the wrong places.

import mock
import 
 unittest
import 
 pinger

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


-- 
DaveA nr


From eryksun at gmail.com  Fri Jan 17 22:02:36 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 17 Jan 2014 16:02:36 -0500
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <20140117153233.GI3915@ando>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
 <20140117112337.GH3915@ando>
 <CACL+1avVwuCT3j=O_k26r7r91qA-ev10pJfgw+SeDf+b99rUBw@mail.gmail.com>
 <20140117153233.GI3915@ando>
Message-ID: <CACL+1as9C+-md6N8mzHAHpHG0TrkPpzwYQ-M6ii+Z1UYCOj4Qg@mail.gmail.com>

On Fri, Jan 17, 2014 at 10:32 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> import mockimport
> unittestimport
> pinger
>
>
> would not be "fine".

Screenshot:
http://i.imgur.com/wSihI1X.png

The following is in a <pre> tag, so the whitespace is rendered literally:

<span style=S0>import</span> mock
<span style=S0>import</span> <span style=S1>unittest</span>
<span style=S0>import</span> pinger

<span style=S0>class</span>

---

Replace S0 and S1 as follows:

    S0 = "color:rgb(255,119,0);font-weight:bold"
    S1 = "color:rgb(220,20,60)"

There's a non-breaking space on the otherwise empty line between
"pinger" and "class".

From steve at pearwood.info  Sat Jan 18 01:49:34 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 18 Jan 2014 11:49:34 +1100
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <lbbk7e$b1s$1@ger.gmane.org>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
 <20140117112337.GH3915@ando>
 <CACL+1avVwuCT3j=O_k26r7r91qA-ev10pJfgw+SeDf+b99rUBw@mail.gmail.com>
 <20140117153233.GI3915@ando> <lbbk7e$b1s$1@ger.gmane.org>
Message-ID: <20140118004934.GK3915@ando>

On Fri, Jan 17, 2014 at 11:05:24AM -0500, Dave Angel wrote:
>  Steven D'Aprano <steve at pearwood.info> Wrote in message:

> > import mockimport 
> > unittestimport 
> > pinger
> > 
> > 
> > would not be "fine".
> > 
> > 
> You're putting the linefeeds in the wrong places.

Of course I am! 

You would be amazed at how long I had to stare at this before I even 
noticed the import suffix at the end of the first two lines. I had 
actually convinced myself that somehow two of the three "import" words 
had been deleted, not just whitespace.

It's all clear to me now, the raw HTML code in James' email had:

  <span style="color:rgb(255,119,0);font-weight:bold">import</span> mock
  <span style="color:rgb(255,119,0);font-weight:bold">import</span> <span 
  style="color:rgb(220,20,60)">unittest</span>
  <span style="color:rgb(255,119,0);font-weight:bold">import</span> pinger

(indentation added by me)

which got mangled into plain text as:

  import mockIMPORT unittestIMPORT pinger

(highlighting the latter two imports for emphasis), and not what my 
brain was telling me, which was "import mock unittest pinger".



-- 
Steven

From steve at pearwood.info  Sat Jan 18 01:52:03 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 18 Jan 2014 11:52:03 +1100
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <CAHvkzykPnGq98=vNJyo+ZRCzBAXaE+ZjRPr_a1hJt3XPRB2Byw@mail.gmail.com>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
 <20140117112337.GH3915@ando>
 <CACL+1avVwuCT3j=O_k26r7r91qA-ev10pJfgw+SeDf+b99rUBw@mail.gmail.com>
 <20140117153233.GI3915@ando>
 <CAHvkzykPnGq98=vNJyo+ZRCzBAXaE+ZjRPr_a1hJt3XPRB2Byw@mail.gmail.com>
Message-ID: <20140118005203.GL3915@ando>

On Fri, Jan 17, 2014 at 03:43:58PM +0000, James Chapman wrote:
> Really!
> 
> import mock
> import unittest
> import pinger
> 
> It should be three lines, but somehow it got all messed up, either
> through rich text formatting or copy paste.

Yes, I see what's going on now, excuse the noise. But this is a good 
example of why HTML-based rich text is rubbish.


> Being a bit pedantic now about import statements which are clearly
> unintentionally messed up.

You're asking for help on a mailing list aimed at beginners. It is very 
common to have beginners post code which cannot possible run and claim 
that it is the version of the code they ran. How are we supposed to tell 
which screw ups are unintentional and which are intentional?



-- 
Steven

From alan.gauld at btinternet.com  Sat Jan 18 02:20:35 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 18 Jan 2014 01:20:35 +0000
Subject: [Tutor] Mocking with "mock" in unit testing
In-Reply-To: <20140118004934.GK3915@ando>
References: <CAHvkzy=S4LJabm6Jxzwu3fVz3vxV+UNF4Y5MntBFy2QqjZYh3g@mail.gmail.com>
 <CACL+1auAMrQf3pTBdmu1gCSD9yw165Mr+A+k2tjqdy5Lezngwg@mail.gmail.com>
 <CAHvkzyntNnFXkHgJfk=toUE6TDGv03CF0qoL73ASpKKGVjuhMg@mail.gmail.com>
 <20140117112337.GH3915@ando>
 <CACL+1avVwuCT3j=O_k26r7r91qA-ev10pJfgw+SeDf+b99rUBw@mail.gmail.com>
 <20140117153233.GI3915@ando> <lbbk7e$b1s$1@ger.gmane.org>
 <20140118004934.GK3915@ando>
Message-ID: <lbcksn$70q$1@ger.gmane.org>

On 18/01/14 00:49, Steven D'Aprano wrote:

> which got mangled into plain text as:
>
>    import mockIMPORT unittestIMPORT pinger
>
> (highlighting the latter two imports for emphasis), and not what my
> brain was telling me, which was "import mock unittest pinger".

If its any consolation I did exactly the same.

Even after the correction came out and I went back to the
original I still missed the import.

It was only when the raw HTML came through I saw it...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From keithwins at gmail.com  Sat Jan 18 09:51:56 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 18 Jan 2014 03:51:56 -0500
Subject: [Tutor] iterators
Message-ID: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>

I don't really get iterators. I saw an interesting example on
Stackoverflow, something like

with open('workfile', 'r') as f:
    for a, b, c in zip(f, f, f):
....

And this iterated through a, b, c assigned to 3 consecutive lines of
the file as it iterates through the file. I can sort of pretend that
makes sense, but then I realize that other things that I thought were
iterators aren't (lists and the range function)... I finally succeeded
in mocking this up with a generator:

gen = (i for i in range(20))
for t1, t2, t3 in zip(gen, gen, gen):
    print(t1, t2, t3)

So I'm a little more confident of this... though I guess there's some
subtlety of how zip works there that's sort of interesting. Anyway,
the real question is, where (why?) else do I encounter iterators,
since my two favorite examples, aren't... and why aren't they, if I
can iterate over them (can't I? Isn't that what I'm doing with "for
item in list" or "for index in range(10)")?

-- 
Keith

From kwpolska at gmail.com  Sat Jan 18 10:22:20 2014
From: kwpolska at gmail.com (=?UTF-8?B?Q2hyaXMg4oCcS3dwb2xza2HigJ0gV2Fycmljaw==?=)
Date: Sat, 18 Jan 2014 10:22:20 +0100
Subject: [Tutor] iterators
In-Reply-To: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
Message-ID: <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>

On Sat, Jan 18, 2014 at 9:51 AM, Keith Winston <keithwins at gmail.com> wrote:
> I don't really get iterators. I saw an interesting example on
> Stackoverflow, something like
>
> with open('workfile', 'r') as f:
>     for a, b, c in zip(f, f, f):
> ....
>
> And this iterated through a, b, c assigned to 3 consecutive lines of
> the file as it iterates through the file. I can sort of pretend that
> makes sense, but then I realize that other things that I thought were
> iterators aren't (lists and the range function)... I finally succeeded
> in mocking this up with a generator:
>
> gen = (i for i in range(20))
> for t1, t2, t3 in zip(gen, gen, gen):
>     print(t1, t2, t3)

For Python 2, use xrange() instead to get an iterator.  In Python 3,
range() is already an iterator.

> So I'm a little more confident of this... though I guess there's some
> subtlety of how zip works there that's sort of interesting. Anyway,
> the real question is, where (why?) else do I encounter iterators,
> since my two favorite examples, aren't... and why aren't they, if I
> can iterate over them (can't I? Isn't that what I'm doing with "for
> item in list" or "for index in range(10)")?

range() actually returns a list.  Lists are not iterators, as next(L)
would?ve told you:

In [1]: next([1, 2])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-8f9d1ea34edf> in <module>()
----> 1 next([1, 2])

TypeError: list object is not an iterator

You can, however, get an iterator of a list, by doing iter(L):

In [2]: iter([1, 2])
Out[2]: <listiterator at 0x2ef1dd0>

Moreover:

> The ``for`` statement is used to iterate over the elements of a
> sequence (such as a string, tuple or list) or other iterable object.
                                                    (from help('for'))

Basically, this is how `for i in X` works:

1. get an iterator by calling X.__iter__() (equivalent to iter(X))
2. assign `i` to X.next() (or X.__next__() in Python 3; equivalent to next(X))
3. if a `break` statement occurs anywhere, get out of the `for` block;
   elif StopIteration is raised, the `else` block is executed (if any)
                                 and then the program continues;
   else, go to step 2.

Here is a poor man?s pure-python re-implementation of `for`:
https://gist.github.com/Kwpolska/8488091

This should clear up most of your doubts.

-- 
Chris ?Kwpolska? Warrick <http://kwpolska.tk>
PGP: 5EAAEA16
stop html mail | always bottom-post | only UTF-8 makes sense

From __peter__ at web.de  Sat Jan 18 10:50:21 2014
From: __peter__ at web.de (Peter Otten)
Date: Sat, 18 Jan 2014 10:50:21 +0100
Subject: [Tutor] iterators
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
Message-ID: <lbdint$kso$1@ger.gmane.org>

Keith Winston wrote:

> I don't really get iterators. I saw an interesting example on
> Stackoverflow, something like
> 
> with open('workfile', 'r') as f:
>     for a, b, c in zip(f, f, f):
> ....
> 
> And this iterated through a, b, c assigned to 3 consecutive lines of
> the file as it iterates through the file. I can sort of pretend that
> makes sense, but then I realize that other things that I thought were
> iterators aren't (lists and the range function)... I finally succeeded
> in mocking this up with a generator:
> 
> gen = (i for i in range(20))
> for t1, t2, t3 in zip(gen, gen, gen):
>     print(t1, t2, t3)
> 
> So I'm a little more confident of this... though I guess there's some
> subtlety of how zip works there that's sort of interesting. Anyway,
> the real question is, where (why?) else do I encounter iterators,
> since my two favorite examples, aren't... and why aren't they, if I
> can iterate over them (can't I? Isn't that what I'm doing with "for
> item in list" or "for index in range(10)")?

You can get an iterator from a list or range object by calling iter():

>>> iter([1, 2, 3])
<list_iterator object at 0xeb0510>
>>> iter(range(10))
<range_iterator object at 0xeaccf0>

Every time you call iter on a sequence you get a new iterator, but when you 
call iter() on an iterator the iterator should return itself.

An iter() call is done implicitly by a for loop, but every time you call 
iter() on a sequence you get a new iterator object. So you can think of the 
for-loop

for item in range(10):
    print(item)

as syntactic sugar for

tmp = iter(range(10))
while True:
    try:
        item = next(tmp)
    except StopIteration:
        break
    print(item)

Back to your zip() example. Here is a possible implementation of zip():

>>> def myzip(*iterables):
...     iterators = [iter(it) for it in iterables]
...     while True:
...             t = tuple(next(it) for it in iterators)
...             if len(t) < len(iterators):
...                     break
...             yield t
... 

When you pass it a range object twice there will be two distinct iterators 
in the `iterators` list that are iterated over in parallel

>>> rfive = range(5)
>>> list(myzip(rfive, rfive))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]

but when you pass the same iterator twice because 
iter(some_iter) is some_iter 
holds (i. e. the iter() function is "idempotent")

next(iterators[0])

and

next(iterators[1])

operate on the same iterator and you get the behaviour seen at 
stackoverflow:

>>> ifive = iter(range(5))
>>> list(myzip(ifive, ifive))
[(0, 1), (2, 3)]

PS: There is an odd difference in the behaviour of list-comps and generator 
expressions. The latter swallow Stopiterations which is why the above 
myzip() needs the len() test:

>>> iterators = [iter(range(3))] * 10
>>> [next(it) for it in iterators]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
StopIteration
>>> iterators = [iter(range(3))] * 10
>>> tuple(next(it) for it in iterators)
(0, 1, 2)

With a list-comp myzip could be simplified:

>>> def myzip(*iterables):
...     iterators = [iter(it) for it in iterables]
...     while True:
...         t = [next(it) for it in iterators]
...         yield tuple(t)
... 
>>> list(myzip(*[iter(range(10))]*3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]



From denis.spir at gmail.com  Sat Jan 18 12:13:02 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 18 Jan 2014 12:13:02 +0100
Subject: [Tutor] iterators
In-Reply-To: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
Message-ID: <52DA61BE.2070902@gmail.com>

On 01/18/2014 09:51 AM, Keith Winston wrote:
> I don't really get iterators. I saw an interesting example on
> Stackoverflow, something like
>
> with open('workfile', 'r') as f:
>      for a, b, c in zip(f, f, f):
> ....
>
> And this iterated through a, b, c assigned to 3 consecutive lines of
> the file as it iterates through the file. I can sort of pretend that
> makes sense, but then I realize that other things that I thought were
> iterators aren't (lists and the range function)... I finally succeeded
> in mocking this up with a generator:
>
> gen = (i for i in range(20))
> for t1, t2, t3 in zip(gen, gen, gen):
>      print(t1, t2, t3)
>
> So I'm a little more confident of this... though I guess there's some
> subtlety of how zip works there that's sort of interesting. Anyway,
> the real question is, where (why?) else do I encounter iterators,
> since my two favorite examples, aren't... and why aren't they, if I
> can iterate over them (can't I? Isn't that what I'm doing with "for
> item in list" or "for index in range(10)")?

An iterator is a kind of object that delivers items once at a time. It is to be 
used with python's "for ... in ..." construct.

Concretely, for each pass of such 'for' cycle, python calls the iterator's 
__next__ method. If the call returns an item, it is used in the pass; if the 
call raises StopIteration, then the cycle stops. Here are two examples of 
iterators (first ignore the __iter__ method, see below) and their usage:

======================================================
class Cubes:
     def __init__ (self, max):
         self.num = 0
         self.max = max

     def __next__ (self):
         if self.num > self.max:
             raise StopIteration()
         item = self.num * self.num * self.num
         self.num += 1
         return item

     def __iter__ (self):
         return self

cubes9 = Cubes(9)

for cube in cubes9:
     print(cube, end=' ')
print()

class Odds:
     def __init__ (self, lst):
         self.idx = 0
         self.lst = lst

     def __next__ (self):
         # find next odd item, if any:
         while self.idx < len(self.lst):
             item = self.lst[self.idx]
             self.idx += 1
             if item % 2 == 1:
                 return item
         # if none:
         raise StopIteration()

     def __iter__ (self):
         return self

l = [0,1,2,3,4,5,6,7,8,9,10]
odds = Odds(l)
for odd in odds:
     print(odd, end=' ')
print()
======================================================

As you can see, the relevant bit is the __next__ method. This and __iter__ are 
the 2 slots forming the "iterator protocol", that iterators are required to 
conform with.

There is a little subtlety: sequences like lists are not iterators. For users to 
be able to iterate over sequences like lists, directly, *in code*:
	for item in lst:
instead of:
	for item in iter(lst):
python performs a little magic: if the supposed iterator passed (here lst) is 
not an iterator in fact, then python looks for an __iter__ method in it, calls 
it if found, and if this returns an iterator (respecting the iterator protocal), 
then it uses that iterator instead. This is why actual iterators are required to 
also have an __iter__ method, so that iterators and sequences can be used in 
'for' loops indifferently. Since iterators are iterators, __iter__ just returns 
self in their case.

Exercise: simulate python's iterator magic for lists. Eg make a 'List' type 
(subtype of list) and implement its __iter__ method. This should create an 
iterator object of type, say, ListIter which itself implements the iterator 
protocal, and indeed correctly provides the list's items. (As you may guess, it 
is a simpler version of my Odd type above.) (Dunno how to do that for sets or 
dicts, since on the python side we have no access I know of to their actual 
storage of items/pairs. In fact, this applies to lists as well, but indexing 
provides indirect access.)

[Note, just to compare: in Lua, this little magic making builtin sequences 
special does not exist. So, to iterate over all items or pairs of a Lua table, 
one would write explicitely, resp.:
	for key,val in pairs(t)
	for item in ipairs(t)
where pairs & ipairs resp. create iterators for (key,val) pairs or indexed items 
of a table (used as python lists or dicts). Functions pairs & ipairs are 
builtin, but it's also trivial to make iterators (or generators) in Lua, since 
it has 'free' objects we don't even need classes for that.]

Now, one may wonder why sequences don't implement the iterator protocal 
themselves (actually, just __next__) and get rid of all that mess? Well, this 
mess permits:
* a variety of traversal, with corresponding different iterators, for the *same* 
(kind of) collections; for instance traversing a list backward, traversing trees 
breadth-first or depth-first or only their leaves, or only nodes with elements...
* the same collection to be traversed in several loops at once (rarely needed, 
but still); concretely nested loops (in principle also from multiple threads 
concurrently); and this does not break (as long as the list itself remains 
unchanged)

Now, you may imagine that, since there are builtin iterators for all of python's 
"iteratable" types, and the corresponding magic is also builtin, and custom 
types are constructed from builtin ones, then there is rarely a need for making 
custom iterators and mastering the corresponding lower-level functioning. And 
you'd certainly be right ;-)

Why do you want to explore that, now?

Denis


From denis.spir at gmail.com  Sat Jan 18 12:16:05 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 18 Jan 2014 12:16:05 +0100
Subject: [Tutor] iterators -- oops!
In-Reply-To: <52DA61BE.2070902@gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <52DA61BE.2070902@gmail.com>
Message-ID: <52DA6275.7070305@gmail.com>

erratum:

On 01/18/2014 12:13 PM, spir wrote:
> [Note, just to compare: in Lua, this little magic making builtin sequences
> special does not exist. So, to iterate over all items or pairs of a Lua table,
> one would write explicitely, resp.:
>      for key,val in pairs(t)
>      for item in ipairs(t)
> where pairs & ipairs resp. create iterators for (key,val) pairs or indexed items
> of a table (used as python lists or dicts). Functions pairs & ipairs are
> builtin, but it's also trivial to make iterators (or generators) in Lua, since
> it has 'free' objects we don't even need classes for that.]

Read instead:

       for _, item in ipairs(t)
       for idx, item in ipairs(t)

Lua's builtin 'ipairs' returns both index and item.
[Never post a piece of code you have not run ;-)]

Denis

From reuben.dlink at gmail.com  Sat Jan 18 18:51:27 2014
From: reuben.dlink at gmail.com (Reuben)
Date: Sat, 18 Jan 2014 23:21:27 +0530
Subject: [Tutor] Understanding Decorators
Message-ID: <CAN89Acp6WAe-AsLxcFSYvFawLCbOujzZUtitjVvm22cvGY4Uzw@mail.gmail.com>

Hi,

I tried reading information regarding decorators - but not able to get a
good grip around it.

Kindly point me to some good links along with examples

Regards,
Reuben
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140118/05f42793/attachment.html>

From eryksun at gmail.com  Sat Jan 18 19:11:51 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 18 Jan 2014 13:11:51 -0500
Subject: [Tutor] iterators
In-Reply-To: <lbdint$kso$1@ger.gmane.org>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <lbdint$kso$1@ger.gmane.org>
Message-ID: <CACL+1avw4oOjb-ktVYDgif9hDdYBFFJ4mDxUT76SaiG1x+EesQ@mail.gmail.com>

On Sat, Jan 18, 2014 at 4:50 AM, Peter Otten <__peter__ at web.de> wrote:
>
> PS: There is an odd difference in the behaviour of list-comps and generator
> expressions. The latter swallow Stopiterations which is why the above
> myzip() needs the len() test:

A comprehension is building a list in a `for` loop, which won't
swallow a `StopIteration` from the body of the loop itself.

For a generator, an unhandled `StopIteration` propagates to the frame
that called `__next__`. In this case the tuple constructor swallows
the `StopIteration`, as it rightly should. There's no way for it know
the original source of the `StopIteration` exception. You'd have to
use a generator that translates `StopIteration` to a custom exception.
Then use that exception to `break` the `while` loop. But no one sane
would go that far.

>>>> def myzip(*iterables):
> ...     iterators = [iter(it) for it in iterables]
> ...     while True:
> ...         t = [next(it) for it in iterators]
> ...         yield tuple(t)

The C implementation for `zip.__next__` calls `PyTuple_SET_ITEM` in a
loop over the iterators. It reuses the same tuple so long as the
reference count is only 1. That can't be duplicated in pure Python.
You'd have to use a `list`.

From eryksun at gmail.com  Sat Jan 18 19:24:31 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 18 Jan 2014 13:24:31 -0500
Subject: [Tutor] Understanding Decorators
In-Reply-To: <CAN89Acp6WAe-AsLxcFSYvFawLCbOujzZUtitjVvm22cvGY4Uzw@mail.gmail.com>
References: <CAN89Acp6WAe-AsLxcFSYvFawLCbOujzZUtitjVvm22cvGY4Uzw@mail.gmail.com>
Message-ID: <CACL+1avdNumXeoz7zGrGfL5dmnm+GtmL24xspYnQKC29OvEt+Q@mail.gmail.com>

On Sat, Jan 18, 2014 at 12:51 PM, Reuben <reuben.dlink at gmail.com> wrote:
>
> I tried reading information regarding decorators - but not able to get a
> good grip around it.
>
> Kindly point me to some good links along with examples

Decorators I: Introduction to Python Decorators
http://www.artima.com/weblogs/viewpost.jsp?thread=240808

How can I make a chain of function decorators in Python?
http://stackoverflow.com/a/1594484

What does functools.wraps do?
http://stackoverflow.com/a/309000

From eryksun at gmail.com  Sat Jan 18 20:19:30 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 18 Jan 2014 14:19:30 -0500
Subject: [Tutor] iterators
In-Reply-To: <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
Message-ID: <CACL+1atv0CNwNvdjdkLtMpFSrLpV70P1DEexsrv5zxE7j2MQJQ@mail.gmail.com>

On Sat, Jan 18, 2014 at 4:22 AM, Chris ?Kwpolska? Warrick
<kwpolska at gmail.com> wrote:
> For Python 2, use xrange() instead to get an iterator.  In Python 3,
> range() is already an iterator.

`xrange` and 3.x `range` aren't iterators. They're sequences. A
sequence implements `__len__` and `__getitem__`, which can be used to
implement an iterator, reversed iterator, and the `in` operator (i.e.
`__contains__`).

    class Sequence:

        def __len__(self):
            return 3

        def __getitem__(self, k):
            if k > 2:
                raise IndexError
            return k

    >>> seq = Sequence()
    >>> len(seq)
    3

    >>> type(iter(seq))
    <class 'iterator'>
    >>> list(seq)
    [0, 1, 2]

    >>> type(reversed(seq))
    <class 'reversed'>
    >>> list(reversed(seq))
    [2, 1, 0]

    >>> 0 in seq
    True
    >>> 3 in seq
    False

`xrange` and Py3 `range` both implement the following special methods:

    __len__
    __getitem__
    __iter__
    __reversed__

3.x `range` also implements:

    __contains__
    index
    count

Neither supports sequence concatenation or repetition. Both are
manually registered as a subclass of the abstract class
`collections.Sequence`.

    >>> issubclass(range, collections.Sequence)
    True

http://docs.python.org/3/library/collections.abc

From keithwins at gmail.com  Sun Jan 19 00:28:46 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 18 Jan 2014 18:28:46 -0500
Subject: [Tutor] iterators
In-Reply-To: <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
Message-ID: <CAO5ffbaH_RtKWVGEL4xZPtx3dO19bV+hRZ7Fyvk+h9URZAfQPA@mail.gmail.com>

On Sat, Jan 18, 2014 at 4:22 AM, Chris ?Kwpolska? Warrick
<kwpolska at gmail.com> wrote:
> Here is a poor man?s pure-python re-implementation of `for`:
> https://gist.github.com/Kwpolska/8488091

This will be very handy the next time I run out of for's, or have a
surplus of while's. Fairly common.

Seriously though, thanks for your comments.

-- 
Keith

From keithwins at gmail.com  Sun Jan 19 00:24:58 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 18 Jan 2014 18:24:58 -0500
Subject: [Tutor] iterators
In-Reply-To: <CACL+1atv0CNwNvdjdkLtMpFSrLpV70P1DEexsrv5zxE7j2MQJQ@mail.gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
 <CACL+1atv0CNwNvdjdkLtMpFSrLpV70P1DEexsrv5zxE7j2MQJQ@mail.gmail.com>
Message-ID: <CAO5ffbb19XUPfaxoCXapeg=1e0ehqU0sQEV69CwbqrNhrh0FMA@mail.gmail.com>

On Sat, Jan 18, 2014 at 2:19 PM, eryksun <eryksun at gmail.com> wrote:
> `xrange` and 3.x `range` aren't iterators. They're sequences. A
> sequence implements `__len__` and `__getitem__`, which can be used to
> implement an iterator, reversed iterator, and the `in` operator (i.e.
> `__contains__`).

I'm so glad you said this, I'm sorta burned out right now trying to
read all this, and I got sorta confused by that part. But what you're
saying is what I thought I understood.

Okay, now your example is pretty interesting. I guess it makes sense
that iter() returns a type iterator. Sure, of course.

Thanks as always to everyone, this is a trove. I'm a bit under the
weather so I'll have to come back and read it closer. I'm a little
clearer, though, and not just on iterators...

-- 
Keith

From jackiexxduh at yahoo.com  Sat Jan 18 23:52:11 2014
From: jackiexxduh at yahoo.com (Jackie Canales)
Date: Sat, 18 Jan 2014 14:52:11 -0800 (PST)
Subject: [Tutor] Question in regards to my assignment
Message-ID: <1390085531.78270.YahooMailNeo@web121703.mail.ne1.yahoo.com>

I have with my assignment.


class Score:
? ? 'A subclass of the object.'
? ??
? ? def __init__(self, init):
? ? ? ? 'Sets the initial score to the object and sets the number of scores that have contributed to the total to 1.'
? ? ? ? self.x = 1
? ? ? ? self.init = int(init)
? ? ? ? self.total = int(init)
? ? ? ??
? ??
? ? def updateOne(self, amount=0):
? ? ? ? 'Increases the total score of the object by amount and Increases the number of scores contributing to the total by 1.'
? ? ? ? self.x += 1
? ? ? ? self.total += amount
? ? ? ? return self.total
? ??
? ? def updateMany(self, lst=0):
? ? ? ? 'Updates the total by the sum of all the scores in the list and number of scores contributing to the total by the number of items found in the list.'
? ? ? ? self.x += len(lst)
? ? ? ? self.total += sum(lst)
? ? ? ? return self.total

? ??
? ? def get(self):
? ? ? ? 'Returns the current score in the object.'
? ? ? ? return self.total

? ? def average(self):
? ? ? ? 'Returns the average of the scores that have contributed to the total score.'
? ? ? ? return self.total/self.x

? ? def __repr__(self):
? ? ? ? 'Returns the canonical representation of the object.'
? ? ? ? return repr(self.total)
? ??
def processScores(filename):
? ? infile = open(filename, 'r')
? ? line = infile.readlines()
? ? infile.close()
? ??
? ?
? ? lineNum = 0
? ? s = Score(0)

? ? for item in line2:
? ? ? ? lineNum += 1
? ? ? ??
? ? ? ? if lineNum == 1:
? ? ? ? ? ? s.total = int(item)
? ? ? ? ? ? print("Score set to total value:", s.total)
? ? ? ? elif lineNum % 2:
? ? ? ? ? ? s.total = int(item)
? ? ? ? ? ? if type(item) == list:
? ? ? ? ? ? ? ? lstNum = s.updateMany(s.total)
? ? ? ? ? ? ? ? print("List detected. Updating many. Total outcome:", lstNum)
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? intNum = s.updateOne(s.total)
? ? ? ? ? ? ? ? print("Numeric detected. Updating One. Total outcome:", intNum)
? ? ? ? else:
? ? ? ? ? ? pass
? ? print("The Final Score is:", s.get())
? ? print("The Average Score is:", s.average())
? ? print("The Score Object is:", s.__repr__())


The file that I am trying read is a text file call score:
5
o?
7
o?
10
m?
[3, 12, 1]
o
8
M?
[1, 2, 3]

The instruction for the assignment are as followed
The first line of the file is a number, which indicates the initial score for a Score object.? The remaining lines are pairs: the even-numbered lines contain a character and the odd-numbered lines contain either a number or a list.? The character will be one of 'o', 'O', 'm', or 'M', indicating that the next line contains either a single score ('o'? or 'O') or a list of scores ('m' or 'M').? The function will create a new?Score?object and then process each line or pairs of lines of the file by calling the appropriate method of the?Score?object.? As it processes each line or pairs of lines, it will print the information about the action being taken.? The first line will be a call to the constructor and the remaining pairs of lines will be calls either to the?updateOne() or?updateMany()methods.? Once the file has been processed, the function will print the final score, the average score, and return the?Score?object.


The error i am getting is:

Traceback (most recent call last):
? File "<pyshell#1>", line 1, in <module>
? ? processScores('scores.txt')
? File "C:/Users/Michael/Documents/DePaul/tutor/hw2_practice.py", line 52, in processScores
? ? s.total = int(item)
ValueError: invalid literal for int() with base 10: '[3, 12, 1]\n'

So from my understanding when my code tries to read the first line with a list it is not able to read ''[3, 12, 1]\n'" because its not able to read "[" as a numeric value so am I suppose to write a loop that enables an exception error. I believe the this is what holding my final product from being complete.Believe is what my output is?

?processScores('scores.txt')
Score set to total value: 5
Numeric detected. Updating One. Total outcome: 14
Numeric detected. Updating One. Total outcome: 20
Traceback (most recent call last):
? File "<pyshell#5>", line 1, in <module>
? ? processScores('scores.txt')
? File "C:/Users/Michael/Documents/DePaul/tutor/hw2_practice.py", line 52, in processScores
? ? s.total = int(item)
ValueError: invalid literal for int() with base 10: '[3, 12, 1]\n'
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140118/b0ea5155/attachment.html>

From pierre.dagenais at ncf.ca  Sat Jan 18 19:07:00 2014
From: pierre.dagenais at ncf.ca (Pierre Dagenais)
Date: Sat, 18 Jan 2014 13:07:00 -0500
Subject: [Tutor] ValueError: could not convert string to float: '13,2'
In-Reply-To: <CAO5ffbagFJTxt2YuTDsA-H5SYuvdKzROG3DG5SSO_2gYG98FCA@mail.gmail.com>
References: <52C2CC62.60300@ncf.ca>
 <CAO5ffbagFJTxt2YuTDsA-H5SYuvdKzROG3DG5SSO_2gYG98FCA@mail.gmail.com>
Message-ID: <52DAC2C4.7090501@ncf.ca>



On 13-12-31 04:09 PM, Keith Winston wrote:
> Hi PierreD, I think if you iterate over your strings with something like
> this, it will do what you want, if I understand correctly (snum is your
> string number, like "123,321"):
> 
> fnum = float(snum.replace(",", ".")
> 
> keith: rank beginner, take everything with a grain of salt!
> 
> 
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 
Thank you all who responded, for now I'll go with Keith's solution and
keep the locale for next time.
As all the data has one digit after the decimal I can get away with
myInt = int(temp.replace(',',''))
to convert a string representation of a float to an integer. I'll just
need to remember to divide everything by ten once the calculations are
done. Not very elegant, but it'll work. I don't suppose there is a
function for determining the number of digits after the decimal, is it?
Also, anybody knows the maximum and/or minimum integer python will accept?

Thank you,
PierreD.

From pierre.dagenais at ncf.ca  Sat Jan 18 19:20:55 2014
From: pierre.dagenais at ncf.ca (Pierre Dagenais)
Date: Sat, 18 Jan 2014 13:20:55 -0500
Subject: [Tutor] Naming variables
Message-ID: <52DAC607.6040406@ncf.ca>

Hello,

I wish to fill a list called years[] with a hundred lists called
year1900[], year1901[], year1902[], ..., year1999[]. That is too much
typing of course. Any way of doing this in a loop? I've tried stuff like
("year" + str(1900)) = [0,0] but nothing works.
Any solution?

Thank you,

PierreD.

From alan.gauld at btinternet.com  Sun Jan 19 02:21:25 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 01:21:25 +0000
Subject: [Tutor] Question in regards to my assignment
In-Reply-To: <1390085531.78270.YahooMailNeo@web121703.mail.ne1.yahoo.com>
References: <1390085531.78270.YahooMailNeo@web121703.mail.ne1.yahoo.com>
Message-ID: <lbf9a9$uge$1@ger.gmane.org>

On 18/01/14 22:52, Jackie Canales wrote:

> def processScores(filename):
>      infile = open(filename, 'r')
>      line = infile.readlines()
>      infile.close()
>      lineNum = 0
>      s = Score(0)
>
>      for item in line2:
 >          lineNum += 1

What is line2? I assume you mean line?

You could do all of the above more easily with

with open(filename) as infile:
     for lineNum, line in enumerate(infile):

But line will *always* be a string so you need to convert the string 
into data that Python can understand. int() works if the line contains a 
numerical string.
But it won't work for lists, and neither will list() for that matter.
You need to remove the brackets then split the lstring by commas and 
then convert each element. Its probably complex enough to warrant a 
function of its own...


>          if lineNum == 1:
>              s.total = int(item)
>              print("Score set to total value:", s.total)
>          elif lineNum % 2:
>              s.total = int(item)
>              if type(item) == list:

You probably want to test type before trying to convert to an int(). 
Unfortunately the type will be a string so the list test will always 
fail. You need to actually examine the string content. (Or you can trust 
the file to tell you, the instructions say a list is flagged by an m/M 
in the line before. So instead of throwing that data away you can use it 
to direct your program what kind of data to process.


>                  lstNum = s.updateMany(s.total)
>                  print("List detected. Updating many. Total outcome:",
> lstNum)
> else:
>                  intNum = s.updateOne(s.total)
>                  print("Numeric detected. Updating One. Total outcome:",
> intNum)
>          else:
>              pass

else: pass

does nothing so you may as well remove it.

>      print("The Final Score is:", s.get())
>      print("The Average Score is:", s.average())
>      print("The Score Object is:", s.__repr__())
>
>
> The file that I am trying read is a text file call score:

> o
> 10
> m
> [3, 12, 1]

> The first line of the file is a number, which indicates the initial
> score for a Score object.  The remaining lines are pairs: the
> even-numbered lines contain a character and the odd-numbered lines
> contain either a number or a list.  The character will be one of 'o',
> 'O', 'm', or 'M', indicating that the next line contains either a single
> score ('o'  or 'O') or a list of scores ('m' or 'M').


> So from my understanding when my code tries to read the first line with
> a list it is not able to read ''[3, 12, 1]\n'" because its not able to
> read "[" as a numeric value

Correct

> so am I suppose to write a loop that enables an exception error.

I'm not sure what you mean by that, but you do need to write a
function to interpret a string representation of a list.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From eryksun at gmail.com  Sun Jan 19 02:40:29 2014
From: eryksun at gmail.com (eryksun)
Date: Sat, 18 Jan 2014 20:40:29 -0500
Subject: [Tutor] iterators
In-Reply-To: <CAO5ffbb19XUPfaxoCXapeg=1e0ehqU0sQEV69CwbqrNhrh0FMA@mail.gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
 <CACL+1atv0CNwNvdjdkLtMpFSrLpV70P1DEexsrv5zxE7j2MQJQ@mail.gmail.com>
 <CAO5ffbb19XUPfaxoCXapeg=1e0ehqU0sQEV69CwbqrNhrh0FMA@mail.gmail.com>
Message-ID: <CACL+1atskMMj6YSZ_xhtNd45Yjho4ZQLqT=YvfszbVPjbC-5rg@mail.gmail.com>

On Sat, Jan 18, 2014 at 6:24 PM, Keith Winston <keithwins at gmail.com> wrote:
>
> I guess it makes sense that iter() returns a type iterator.

`iter(obj)` returns `obj.__iter__()` if the method exists and the
result is an iterator, i.e. has a `__next__` method.

Otherwise if `obj.__getitem__` exists, it returns a generic sequence
`iterator`. This steps through the sequence `obj[0]`, `obj[1]`, and so
on, until it encounters either `IndexError` or `StopIteration`.

`iter(callable, sentinel)` returns a `callable_iterator`. This returns
`callable()` until either the result equals `sentinel` or it
encounters `StopIteration`. For example:

    >>> sentinel = 2
    >>> it = iter(iter(range(5)).__next__, sentinel)
    >>> type(it)
    <class 'callable_iterator'>
    >>> list(it)
    [0, 1]

`reversed(obj)` returns `obj.__reversed__()`, if it exists. It doesn't
check the type of the result:

    class C:
        __reversed__ = lambda s: 3.14

    >>> reversed(C())
    3.14

Otherwise if `obj` is a sequence (`__getitem__`, `__len__`, and not a
`dict`), it returns a `reversed` instance. This iterates from
`obj[len(obj) - 1]` down to `obj[0]`.

From dyoo at hashcollision.org  Sun Jan 19 03:30:08 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 18 Jan 2014 18:30:08 -0800
Subject: [Tutor] Naming variables
In-Reply-To: <52DAC607.6040406@ncf.ca>
References: <52DAC607.6040406@ncf.ca>
Message-ID: <CAGZAPF5BkvHOAMBZqgQgCjzqksP4WPm99sLS_0cFPirXm0JZLw@mail.gmail.com>

If we wanted to do something with something like:

    year0 = 0
    year1 = 0
    year2 = 0
    ...
    year999 = 0

where we keep a thousand years, and set them all to zero, then you're
right in thinking that having one thousand separate variables is
probably not a viable approach.


We can handle this uniformly, though, by using a list.

    year  = [0] * 1000

'year' is now a list with 1000 elements, all of which are zero.  We
can access each in turn:

    year[0]
    year[1]
    year[2]
    ....
    year[999]

and see that they all have zero in them.

From dyoo at hashcollision.org  Sun Jan 19 03:35:15 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sat, 18 Jan 2014 18:35:15 -0800
Subject: [Tutor] Naming variables
In-Reply-To: <CAGZAPF5BkvHOAMBZqgQgCjzqksP4WPm99sLS_0cFPirXm0JZLw@mail.gmail.com>
References: <52DAC607.6040406@ncf.ca>
 <CAGZAPF5BkvHOAMBZqgQgCjzqksP4WPm99sLS_0cFPirXm0JZLw@mail.gmail.com>
Message-ID: <CAGZAPF4O5+J0O+bregPzCZXyn=BfehiT0Kmd8gAY6NBauUbJkA@mail.gmail.com>

One thing to note:  I wrote:

    year = [0] * 1000


Here's another way to get something equivalent:

    year  = []
    for i in range(1000):
        year.append(0)


Here, we do an explicit loop to append those thousand zeros into the
list.  We'll end up with the same situation as before: year is a list
of zeros.


Why would we want to look at doing it this different approach?

See:

    http://docs.python.org/2/faq/programming.html#how-do-i-create-a-multidimensional-list

for details.


Good luck!

From __peter__ at web.de  Sun Jan 19 09:22:13 2014
From: __peter__ at web.de (Peter Otten)
Date: Sun, 19 Jan 2014 09:22:13 +0100
Subject: [Tutor] ValueError: could not convert string to float: '13,2'
References: <52C2CC62.60300@ncf.ca>
 <CAO5ffbagFJTxt2YuTDsA-H5SYuvdKzROG3DG5SSO_2gYG98FCA@mail.gmail.com>
 <52DAC2C4.7090501@ncf.ca>
Message-ID: <lbg1ug$jag$1@ger.gmane.org>

Pierre Dagenais wrote:

> 
> 
> On 13-12-31 04:09 PM, Keith Winston wrote:
>> Hi PierreD, I think if you iterate over your strings with something like
>> this, it will do what you want, if I understand correctly (snum is your
>> string number, like "123,321"):
>> 
>> fnum = float(snum.replace(",", ".")
>> 
>> keith: rank beginner, take everything with a grain of salt!
>> 
>> 
>> 
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> https://mail.python.org/mailman/listinfo/tutor
>> 
> Thank you all who responded, for now I'll go with Keith's solution and
> keep the locale for next time.
> As all the data has one digit after the decimal I can get away with
> myInt = int(temp.replace(',',''))
> to convert a string representation of a float to an integer. I'll just
> need to remember to divide everything by ten once the calculations are
> done. Not very elegant, but it'll work. I don't suppose there is a
> function for determining the number of digits after the decimal, is it?

It looks like you are trying to avoid rounding errors in decimal arithmetic. 
You might be interested in Python's decimal.Decimal type then.

> Also, anybody knows the maximum and/or minimum integer python will accept?

Integers in Python (*) are "unlimited"

>>> 10**1000 -1
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999                                  

In practice the amount of available memory will be the limit, but you are 
unlikely to reach that.

(*) Python 2 had int and long where values that could not represented by 
machine integers were automatically propagated to long. In Python 3 the int 
and long have been united as int.


From __peter__ at web.de  Sun Jan 19 09:27:46 2014
From: __peter__ at web.de (Peter Otten)
Date: Sun, 19 Jan 2014 09:27:46 +0100
Subject: [Tutor] Naming variables
References: <52DAC607.6040406@ncf.ca>
Message-ID: <lbg28t$mgf$1@ger.gmane.org>

Pierre Dagenais wrote:

> I wish to fill a list called years[] with a hundred lists called
> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
> typing of course. Any way of doing this in a loop? I've tried stuff like
> ("year" + str(1900)) = [0,0] but nothing works.
> Any solution?

Use a dict:

years = {}
for year in range(1900, 2000):
    years[year] = [0, 0]

Then instead of

print year1982

you have to type

print years[1982]



From pywkm at wukaem.pl  Sun Jan 19 03:31:30 2014
From: pywkm at wukaem.pl (Wiktor Matuszewski)
Date: Sun, 19 Jan 2014 03:31:30 +0100
Subject: [Tutor] Naming variables
In-Reply-To: <52DAC607.6040406@ncf.ca>
References: <52DAC607.6040406@ncf.ca>
Message-ID: <52DB3902.5000708@wukaem.pl>

W dniu 2014-01-18 19:20, Pierre Dagenais pisze:

> I wish to fill a list called years[] with a hundred lists called
> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
> typing of course. Any way of doing this in a loop? I've tried stuff like
> ("year" + str(1900)) = [0,0] but nothing works.
> Any solution?

Hi,
I don't know the solution, or if there is one.
And because of that, if I were you I would try to contain this data in 
different way. Why not dictionary?

years = {1900: [0,0], 1901: [0,0], ..., 1999: [0,0]}

Initiating this dictionary with empty (or [0,0]) one hundred lists would 
be easy with for loop. Accessing/changing list representing particular 
year is much more easier: years[1980].

-- 
Best regards,     Wiktor Matuszewski  |  Python
'py{}@wu{}em.pl'.format('wkm', 'ka')  |  newbie

From pywkm at wukaem.pl  Sun Jan 19 04:13:33 2014
From: pywkm at wukaem.pl (Wiktor Matuszewski)
Date: Sun, 19 Jan 2014 04:13:33 +0100
Subject: [Tutor] Naming variables
In-Reply-To: <52DAC607.6040406@ncf.ca>
References: <52DAC607.6040406@ncf.ca>
Message-ID: <52DB42DD.5000901@wukaem.pl>

W dniu 2014-01-18 19:20, Pierre Dagenais pisze:
> I wish to fill a list called years[] with a hundred lists called
> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
> typing of course. Any way of doing this in a loop? I've tried stuff like
> ("year" + str(1900)) = [0,0] but nothing works.
> Any solution?

 >>> y = 1900
 >>> exec('year{} = [0, 0]'.format(y))
 >>> year1900
[0, 0]

But I still think, that solution with dict with lists is better.

-- 
Best regards,     Wiktor Matuszewski  |  Python
'py{}@wu{}em.pl'.format('wkm', 'ka')  |  newbie

From denis.spir at gmail.com  Sun Jan 19 13:55:05 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 19 Jan 2014 13:55:05 +0100
Subject: [Tutor] iterators
In-Reply-To: <CAO5ffbb19XUPfaxoCXapeg=1e0ehqU0sQEV69CwbqrNhrh0FMA@mail.gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
 <CACL+1atv0CNwNvdjdkLtMpFSrLpV70P1DEexsrv5zxE7j2MQJQ@mail.gmail.com>
 <CAO5ffbb19XUPfaxoCXapeg=1e0ehqU0sQEV69CwbqrNhrh0FMA@mail.gmail.com>
Message-ID: <52DBCB29.8000209@gmail.com>

On 01/19/2014 12:24 AM, Keith Winston wrote:
> On Sat, Jan 18, 2014 at 2:19 PM, eryksun <eryksun at gmail.com> wrote:
>> `xrange` and 3.x `range` aren't iterators. They're sequences. A
>> sequence implements `__len__` and `__getitem__`, which can be used to
>> implement an iterator, reversed iterator, and the `in` operator (i.e.
>> `__contains__`).
>
> I'm so glad you said this, I'm sorta burned out right now trying to
> read all this, and I got sorta confused by that part. But what you're
> saying is what I thought I understood.
>
> Okay, now your example is pretty interesting. I guess it makes sense
> that iter() returns a type iterator. Sure, of course.
>
> Thanks as always to everyone, this is a trove. I'm a bit under the
> weather so I'll have to come back and read it closer. I'm a little
> clearer, though, and not just on iterators...

There is some inevitable confusion due to the exact usage or definition of given 
terms in (the discourse) about given programming languages, as opposed to more 
general meaings in programming in general (and to a certain point the meaning we 
can infer from the ordinary sense of a term, when applied to programming). 
Python for instance has a very precise usage and definition of "iterator" (as a 
"protocal" for a kind of objects). This leads to some pythonists refusing or 
correcting statements related to iterators which would otherwise be (mostly) 
true in the more general context of programming (or which would be _differently_ 
wrong in the latter context ;-).

'range' ('xrange' in python2) is certainly (at least in my view) a kind of 
iterator in the latter, more general sense used in programming (some thing 
providing items one at a time); however, it does not implement python's iterator 
protocal. Thus, it cannot be used directly in a 'for' traversal loop: if i'm 
right, python builds a python iterator for ranges in the background. Like all 
other kinds of 'sequences' (in the python sense, again) ranges are traversable 
("iteratable") because they can in principle provide items one at a time, and 
there exist builtin iterators for them.

For iterators, in python there is additional confusion with generators (at term 
which AFAIK in programming means either about the same as iterator, or a 
subclass of iterators implemented using poor man's coroutines), precisely 
generator objects; and with generator expressions and other comprehensions.

A bit exaggerately complicated, in my view, esp when considering the narrowness 
of the application field. Maybe a case of over-abstraction or over-engineering?

Denis

From denis.spir at gmail.com  Sun Jan 19 14:23:44 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 19 Jan 2014 14:23:44 +0100
Subject: [Tutor] Naming variables
In-Reply-To: <52DAC607.6040406@ncf.ca>
References: <52DAC607.6040406@ncf.ca>
Message-ID: <52DBD1E0.5000601@gmail.com>

On 01/18/2014 07:20 PM, Pierre Dagenais wrote:
> Hello,
>
> I wish to fill a list called years[] with a hundred lists called
> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
> typing of course. Any way of doing this in a loop? I've tried stuff like
> ("year" + str(1900)) = [0,0] but nothing works.
> Any solution?
>
> Thank you,
>
> PierreD.

I think Danny & Wiktor's solutions are the right ones. Danny's is faster a 
simpler (because of direct array indexing), but does not allow giving the true 
year "names" (actually numbers). Wiktor more correctly matches you expectation 
bt is a bit slower because we're searching individual years in a dict.

Here is an alternative, which should about as slow (since it is also searching 
in a dict), and give true (string) names, at the cost of some complication in 
code. The trick is to make a plain object (unfortunately we need a class in 
python for that: it's a "fantom" class) and then directly set years on it as 
plain attributes. Unfortunately, I don't remember of any nice way to traverse an 
object's attributes: we have to traverse its __dict__ explicitely.

======================================
class Years: pass	# fantom class

years = Years()

# set years as attributes:
start_year = 1900
n_years = 3			# 3 years only as example
for i in range (n_years):
     # use setattr(obj, name, value) :
     name  = "year" + str(start_year + i)
     value = [i]      		# give meaningful value maybe ;-)
     setattr(years, name, value)

# access individual year:
print(years.year1901)

# traverse years:
for name in years.__dict__:
     value = years.__dict__[name]
     # unordered, unfortunately
     print("%s : %s" % (name, value))

""" output (by me: order is undefined):
[1]
year1900 : [0]
year1901 : [1]
year1902 : [2]
"""
======================================

denis

From breamoreboy at yahoo.co.uk  Sun Jan 19 14:59:55 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 19 Jan 2014 13:59:55 +0000
Subject: [Tutor] Naming variables
In-Reply-To: <52DBD1E0.5000601@gmail.com>
References: <52DAC607.6040406@ncf.ca> <52DBD1E0.5000601@gmail.com>
Message-ID: <lbglok$jfg$1@ger.gmane.org>

On 19/01/2014 13:23, spir wrote:
> On 01/18/2014 07:20 PM, Pierre Dagenais wrote:
>> Hello,
>>
>> I wish to fill a list called years[] with a hundred lists called
>> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
>> typing of course. Any way of doing this in a loop? I've tried stuff like
>> ("year" + str(1900)) = [0,0] but nothing works.
>> Any solution?
>>
>> Thank you,
>>
>> PierreD.
>
> I think Danny & Wiktor's solutions are the right ones. Danny's is faster
> a simpler (because of direct array indexing), but does not allow giving
> the true year "names" (actually numbers). Wiktor more correctly matches
> you expectation bt is a bit slower because we're searching individual
> years in a dict.
>

I suspect that the speed difference between accessing a list by direct 
indexing and looking up something in a dict is negligible.  I'll happily 
leave Steven D'Aprano to supply us with the actual figures from the 
timeit module :)

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

Mark Lawrence


From denis.spir at gmail.com  Sun Jan 19 15:21:10 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 19 Jan 2014 15:21:10 +0100
Subject: [Tutor] Naming variables
In-Reply-To: <lbglok$jfg$1@ger.gmane.org>
References: <52DAC607.6040406@ncf.ca> <52DBD1E0.5000601@gmail.com>
 <lbglok$jfg$1@ger.gmane.org>
Message-ID: <52DBDF56.9090005@gmail.com>

On 01/19/2014 02:59 PM, Mark Lawrence wrote:
> On 19/01/2014 13:23, spir wrote:
>> On 01/18/2014 07:20 PM, Pierre Dagenais wrote:
>>> Hello,
>>>
>>> I wish to fill a list called years[] with a hundred lists called
>>> year1900[], year1901[], year1902[], ..., year1999[]. That is too much
>>> typing of course. Any way of doing this in a loop? I've tried stuff like
>>> ("year" + str(1900)) = [0,0] but nothing works.
>>> Any solution?
>>>
>>> Thank you,
>>>
>>> PierreD.
>>
>> I think Danny & Wiktor's solutions are the right ones. Danny's is faster
>> a simpler (because of direct array indexing), but does not allow giving
>> the true year "names" (actually numbers). Wiktor more correctly matches
>> you expectation bt is a bit slower because we're searching individual
>> years in a dict.
>>
>
> I suspect that the speed difference between accessing a list by direct indexing
> and looking up something in a dict is negligible.  I'll happily leave Steven
> D'Aprano to supply us with the actual figures from the timeit module :)

It's 2-3 times slower, I guess (measures in other langs, including lua & 
hand-implemented in C, but not in python). The task is accessing an entry which 
key is a plain natural number, meaning a sparse array. It is typically 
implemented as a "mod table" (my term), meaning a hash table without hashing 
since keys already are natural numbers: only remains the modulo (actually just a 
mask since the base is a power of 2). The overhead is consistently 2-3 times, 
but as you say is often neglectable in practice since time remains small 
compared to whatever one does with data, once accessed.

Lua for this reason nevertheless optimises function local scopes by getting rid 
of names (unless one explicitely uses them, sort of metaprogramming) and 
replacing them with indexes in a plain array (actually kind of custom call 
stack). This is as said 2-3 times faster than access of globals (which names 
remain, but *interned* thus we have a sparse array, and the scope is the Lua 
version of a dict).

I guess (not sure) python optimises access of dicts used as scopes (also of 
object attributes) by interning id-strings and thus beeing able to replace them 
by hash values already computed once for interning, or other numeric codes, as 
keys in dicts. Thus, we fall back to the case of a sparse array as above (but in 
this case names are still there and accessible in the string pool).
[This is my preferred method, despite the additional complication of a string 
pool, and additional weight of the numeric key in strings. And once we have the 
machinary in place, it can be used for other purposes, like interning small user 
strings or, as in python, object attr names.]

Denis

From matbioinfo at gmail.com  Sun Jan 19 14:59:32 2014
From: matbioinfo at gmail.com (rahmad akbar)
Date: Sun, 19 Jan 2014 14:59:32 +0100
Subject: [Tutor] string indexing
Message-ID: <CAD0YXfVLg-ZtY5LYpOEMTuhT83nRYA7G8zMKTEJqyDu5m2RtWQ@mail.gmail.com>

hey guys, super  noob here, i am trying to understand the following code
from google tutorial which i failed to comprehend

#code start
# E. not_bad
# Given a string, find the first appearance of the
# substring 'not' and 'bad'. If the 'bad' follows
# the 'not', replace the whole 'not'...'bad' substring
# with 'good'.
# Return the resulting string.
# So 'This dinner is not that bad!' yields:
# This dinner is good!
def not_bad(s):
  # +++your code here+++
  # LAB(begin solution)
  n = s.find('not')
  b = s.find('bad')
  if n != -1 and b != -1 and b > n:
    s = s[:n] + 'good' + s[b+3:]
  return s
#code end

 on the following lines, what is -1, is that index number? and i dont
understand the entire second line

if n != -1 and b != -1 and b > n:
    s = s[:n] + 'good' + s[b+3:]

-- 
many thanks
mat
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140119/7ee0a904/attachment-0001.html>

From denis.spir at gmail.com  Sun Jan 19 16:41:49 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 19 Jan 2014 16:41:49 +0100
Subject: [Tutor] string indexing
In-Reply-To: <CAD0YXfVLg-ZtY5LYpOEMTuhT83nRYA7G8zMKTEJqyDu5m2RtWQ@mail.gmail.com>
References: <CAD0YXfVLg-ZtY5LYpOEMTuhT83nRYA7G8zMKTEJqyDu5m2RtWQ@mail.gmail.com>
Message-ID: <52DBF23D.5040909@gmail.com>

On 01/19/2014 02:59 PM, rahmad akbar wrote:> hey guys, super  noob here, i am 
trying to understand the following code
> from google tutorial which i failed to comprehend
>
> #code start
> # E. not_bad
> # Given a string, find the first appearance of the
> # substring 'not' and 'bad'. If the 'bad' follows
> # the 'not', replace the whole 'not'...'bad' substring
> # with 'good'.
> # Return the resulting string.
> # So 'This dinner is not that bad!' yields:
> # This dinner is good!
> def not_bad(s):
>    # +++your code here+++
>    # LAB(begin solution)
>    n = s.find('not')
>    b = s.find('bad')
>    if n != -1 and b != -1 and b > n:
>      s = s[:n] + 'good' + s[b+3:]
>    return s
> #code end
>
>   on the following lines, what is -1, is that index number? and i dont
> understand the entire second line

-1 is what find returns if the searched substring is not at all present in the 
bigger string: a trick meaning "could not find it". (-1 also means last index, 
but is not necessary for find, it would return the positive last index)

> if n != -1 and b != -1 and b > n:

a conditions for which 3 sub-conditions must be met at once

>      s = s[:n] + 'good' + s[b+3:]

Watch this:

     string:    This dinner is not that bad!
     indexes:   0              n        b  -1

s[:n]   = s[0:n]    = "This dinner is "
s[b+3:] = s[b+3:-1] = "!"

+ concatenates (glues together) bits of strings

denis

From __peter__ at web.de  Sun Jan 19 16:59:39 2014
From: __peter__ at web.de (Peter Otten)
Date: Sun, 19 Jan 2014 16:59:39 +0100
Subject: [Tutor] string indexing
References: <CAD0YXfVLg-ZtY5LYpOEMTuhT83nRYA7G8zMKTEJqyDu5m2RtWQ@mail.gmail.com>
Message-ID: <lbgso4$r9s$1@ger.gmane.org>

rahmad akbar wrote:

> hey guys, super  noob here, i am trying to understand the following code
> from google tutorial which i failed to comprehend
> 
> #code start
> # E. not_bad
> # Given a string, find the first appearance of the
> # substring 'not' and 'bad'. If the 'bad' follows
> # the 'not', replace the whole 'not'...'bad' substring
> # with 'good'.
> # Return the resulting string.
> # So 'This dinner is not that bad!' yields:
> # This dinner is good!
> def not_bad(s):
>   # +++your code here+++
>   # LAB(begin solution)
>   n = s.find('not')
>   b = s.find('bad')
>   if n != -1 and b != -1 and b > n:
>     s = s[:n] + 'good' + s[b+3:]
>   return s
> #code end
> 
>  on the following lines, what is -1, is that index number? 

Python indices start at 0 and the s.find(t) method returns the starting 
index of the first occurence of t in s. That's 0 when s starts with t:

>>> "badmington".find("bad")
0

When t does not occur in s at all the method returns -1, a value that cannot 
be confused with any other possible starting pos.

>  and i dont
> understand the entire second line
> 
> if n != -1 and b != -1 and b > n:

The above line then means (partly in pseudocode):

if ("not" in s) and ("bad" in s) and ("bad" occurs after "not"):

>     s = s[:n] + 'good' + s[b+3:]

s[:n] for a positive integer n means "take the first n characters of s", or 
everything before the occurence of "not". It's basically a shortcut for 
s[0:n]:

>>> s = "This dinner is not that bad!"
>>> s[:3]
'Thi'
>>> n = s.find("not")
>>> s[:n]
'This dinner is '

Likewise s[b:] for a positive integer b means "take all characters after the 
first n of s, or everything including and after the occurence of "bad". 
Again, you can think of it as a shortcut for s[b:len(s)]:

>>> s[3:]
's dinner is not that bad!'
>>> b = s.find("bad")
>>> s[b:]
'bad!'

But we don't want "bad" in the final string, so we have to ad len("bad") or 
3 to b:

>>> s[b+3:]
'!'

So now we have

>>> s[:n]
'This dinner is '

and 

>>> s[b+3:]
'!'

and can put whatever we like in between:

>>> s[:n] + "really delicious" + s[b+3:]
'This dinner is really delicious!'

PS: Note that Python's slicing notation allows steps and negative indices, 
something you might read up on later.


From oscar.j.benjamin at gmail.com  Sun Jan 19 17:18:52 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Sun, 19 Jan 2014 16:18:52 +0000
Subject: [Tutor] iterators
In-Reply-To: <52DBCB29.8000209@gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
 <CACL+1atv0CNwNvdjdkLtMpFSrLpV70P1DEexsrv5zxE7j2MQJQ@mail.gmail.com>
 <CAO5ffbb19XUPfaxoCXapeg=1e0ehqU0sQEV69CwbqrNhrh0FMA@mail.gmail.com>
 <52DBCB29.8000209@gmail.com>
Message-ID: <CAHVvXxT0Hz4cGAZu-dDOshtb3r=DiYa9rjLUzSSuyZiCa7SoVQ@mail.gmail.com>

On 19 January 2014 12:55, spir <denis.spir at gmail.com> wrote:
>
> 'range' ('xrange' in python2) is certainly (at least in my view) a kind of
> iterator in the latter, more general sense used in programming (some thing
> providing items one at a time); however, it does not implement python's
> iterator protocal. Thus, it cannot be used directly in a 'for' traversal
> loop: if i'm right, python builds a python iterator for ranges in the
> background. Like all other kinds of 'sequences' (in the python sense, again)
> ranges are traversable ("iteratable") because they can in principle provide
> items one at a time, and there exist builtin iterators for them.

It's not really that complicated. Basically range on 3.x (or xrange on
2.x) returns a range object:

$ python3
Python 3.3.2+ (default, Oct  9 2013, 14:56:03)
[GCC 4.8.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = range(2, 4)
>>> a
range(2, 4)

A range object is not an "iterator":

>>> next(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'range' object is not an iterator

However it is an "iterable" which means that I can call iter on it to
get an "iterator":

>>> b = iter(a)
>>> b
<range_iterator object at 0xb70ef770>

Once we have the iterator object we can call next() on it:

>>> next(b)
2
>>> next(b)
3

The distinction between the iterator and the iterable is important
since it affects what happens if we call iter() multiple times:

>>> c = iter(a)
>>> next(c)
2
>>> next(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> next(c)
3
>>> next(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Iterators (as opposed to iterables) must be their own iterator. So
when you call iter you get back the same object:

>>> iter(c) is c
True
>>> iter(c) is b
False
>>> iter(c) is a
False

This means that if we call iter several times we don't start from the
beginning of the sequence of values that come from the iterator.

>>> a = range(9)
>>> a
range(0, 9)

When we iterate over the range object we always get the same values:

>>> for x in a:
...   if x > 3:
...     break
...   print(x)
...
0
1
2
3
>>> for x in a:
...   if x > 5:
...     break
...   print(x)
...
0
1
2
3
4
5

When we iterate over the range_iterator it remembers where it left off:

>>> b = iter(a)
>>> for x in b:
...   if x > 3:
...     break
...   print(x)
...
0
1
2
3
>>> for x in b:
...   if x > 5:
...     break
...   print(x)
...
5

It's important to know whether you have an iterable or an iterator. If
you write a function that should work with either then it's sometimes
necessary to explicitly call iter at the start:

def myfunc(iterable):
    iterator = iter(iterable)
    # Do stuff with iterator

If you just loop over all the values in the iterable once then this is
unneeded. If your iteration pattern is more complicated then you may
need this. This is important if e.g. you have a function that should
work equally well with a file object or with a list of strings or a
generator that yields strings etc. The list object is an iterable but
not an iterator. File objects and generators are iterators.

> For iterators, in python there is additional confusion with generators (at
> term which AFAIK in programming means either about the same as iterator, or
> a subclass of iterators implemented using poor man's coroutines), precisely
> generator objects; and with generator expressions and other comprehensions.
>
> A bit exaggerately complicated, in my view, esp when considering the
> narrowness of the application field. Maybe a case of over-abstraction or
> over-engineering?

What's the narrowness of the application field? Iteration is
fundamental in pretty much every program I write. Iterators and
generators are great at writing scalable programs without needing to
complicate your code. Try doing a similar thing in C where you have to
write call-back functions or functions to allocate and hold on to
iteration state and so on.


Oscar

From alan.gauld at btinternet.com  Sun Jan 19 17:33:58 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 16:33:58 +0000
Subject: [Tutor] string indexing
In-Reply-To: <CAD0YXfVLg-ZtY5LYpOEMTuhT83nRYA7G8zMKTEJqyDu5m2RtWQ@mail.gmail.com>
References: <CAD0YXfVLg-ZtY5LYpOEMTuhT83nRYA7G8zMKTEJqyDu5m2RtWQ@mail.gmail.com>
Message-ID: <lbgupa$gme$1@ger.gmane.org>

On 19/01/14 13:59, rahmad akbar wrote:
> hey guys, super  noob here, i am trying to understand the following code
> from google tutorial which i failed to comprehend

Others have answered the specifics but some general advice here:

1) never forget the Python >>> prompt.
Try things out if you don't understand them.
Look at the results. Its a great learning tool.

2) use the built in help() function at the >>> prompt

Those two aids will answer about 80% of your questions.
And for the rest there is the tutor list! :-)

> def not_bad(s):
>    n = s.find('not')
>    b = s.find('bad')
>    if n != -1 and b != -1 and b > n:
>      s = s[:n] + 'good' + s[b+3:]
>    return s

>   on the following lines, what is -1, is that index number?


 >>> help(''.find)
Help on built-in function find:

find(...)
     S.find(sub[, start[, end]]) -> int

     Return the lowest index in S where substring sub is found,
     such that sub is contained within S[start:end].  Optional
     arguments start and end are interpreted as in slice notation.

     Return -1 on failure.
(END)

 >>> s = "Test string thats not interesting but not bad either"
 >>> s.find('not')
18
 >>> s.find('bad')
42
 >>> s.find('gobbledegook')
-1

> understand the entire second line
> if n != -1 and b != -1 and b > n:
>      s = s[:n] + 'good' + s[b+3:]

Again try this in bits at the >>> prompt:

 >>> s[:18]    # using the value found above
'Test string thats '
 >>> s[42+3:]   # again using value above
' either'
 >>> s[:18] + 'good' + s[45:]
'Test string thats good either'

Hopefully that gives you some ideas on how
to use the >>> prompt to answer questions
as they arise.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Sun Jan 19 17:55:52 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 16:55:52 +0000
Subject: [Tutor] iterators
In-Reply-To: <CAHVvXxT0Hz4cGAZu-dDOshtb3r=DiYa9rjLUzSSuyZiCa7SoVQ@mail.gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
 <CACL+1atv0CNwNvdjdkLtMpFSrLpV70P1DEexsrv5zxE7j2MQJQ@mail.gmail.com>
 <CAO5ffbb19XUPfaxoCXapeg=1e0ehqU0sQEV69CwbqrNhrh0FMA@mail.gmail.com>
 <52DBCB29.8000209@gmail.com>
 <CAHVvXxT0Hz4cGAZu-dDOshtb3r=DiYa9rjLUzSSuyZiCa7SoVQ@mail.gmail.com>
Message-ID: <lbh02b$uv2$1@ger.gmane.org>

On 19/01/14 16:18, Oscar Benjamin wrote:

> It's not really that complicated. Basically range on 3.x (or xrange on
> 2.x) returns a range object:

Sadly though it is complicated, at least for newbies :-(

Python 3 has cleaned up much of the language from a Comp Sci point of 
view but from the point of view of a lay newbie it has exposed lots of 
complicated detritus that means absolutely nothing to them.

What is an iterator? a range object? generators? slots?
Lists and sequences are fairly standard language concepts but these new 
terms are terrifyingly obscure for newbies, especially when they appear 
in error messages.

It has reached the point that I'm back to looking for a new teaching 
language. In Python 3 the decision has clearly been made to focus on
supporting Python's role as a professional software engineering language
at the expense of being a successor to ABC or for use in CP4E etc.
That's a fair enough decision but it does mean Python is no longer the 
easiest option for non Comp Sci beginners. It's not worse than the 
others but it's no longer clearly superior. (IMHO at least! )

But what else is there? that's the problem.... :-(

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From keithwins at gmail.com  Sun Jan 19 19:47:55 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 19 Jan 2014 13:47:55 -0500
Subject: [Tutor] iterators
In-Reply-To: <lbh02b$uv2$1@ger.gmane.org>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
 <CACL+1atv0CNwNvdjdkLtMpFSrLpV70P1DEexsrv5zxE7j2MQJQ@mail.gmail.com>
 <CAO5ffbb19XUPfaxoCXapeg=1e0ehqU0sQEV69CwbqrNhrh0FMA@mail.gmail.com>
 <52DBCB29.8000209@gmail.com>
 <CAHVvXxT0Hz4cGAZu-dDOshtb3r=DiYa9rjLUzSSuyZiCa7SoVQ@mail.gmail.com>
 <lbh02b$uv2$1@ger.gmane.org>
Message-ID: <CAO5ffbY6Ln4U02U-hPejcrn5vT4UXvHh8b1fkJmwSh9OoJ7C-Q@mail.gmail.com>

Well, as usual thanks for all this, it's really great. I'd worked out
that it was a distinction between iterators and iterables, though I'm
going to Oscar's description a few more times: most of it made sense,
but there are subtleties.

For example, this from the Python 3.3 tutorial:

We say such an object is iterable [referring to "range"], that is,
suitable as a target for functions and constructs that expect
something from which they can obtain successive items until the supply
is exhausted. We have seen that the for statement is such an iterator.
The function list() is another; it creates lists from iterables:

Now, everything we've said thus far would not have led me to believe
that one would call the for statement an iterator... is this just
very, very loose use of the term (in the Python documentation!), or am
I still missing something biggish?

K

From oscar.j.benjamin at gmail.com  Sun Jan 19 20:02:11 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Sun, 19 Jan 2014 19:02:11 +0000
Subject: [Tutor] iterators
In-Reply-To: <CAO5ffbY6Ln4U02U-hPejcrn5vT4UXvHh8b1fkJmwSh9OoJ7C-Q@mail.gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
 <CACL+1atv0CNwNvdjdkLtMpFSrLpV70P1DEexsrv5zxE7j2MQJQ@mail.gmail.com>
 <CAO5ffbb19XUPfaxoCXapeg=1e0ehqU0sQEV69CwbqrNhrh0FMA@mail.gmail.com>
 <52DBCB29.8000209@gmail.com>
 <CAHVvXxT0Hz4cGAZu-dDOshtb3r=DiYa9rjLUzSSuyZiCa7SoVQ@mail.gmail.com>
 <lbh02b$uv2$1@ger.gmane.org>
 <CAO5ffbY6Ln4U02U-hPejcrn5vT4UXvHh8b1fkJmwSh9OoJ7C-Q@mail.gmail.com>
Message-ID: <CAHVvXxQyJnt5J5VtxagY-fgyH8MenMtM-myj59PdBRVjHCKHXA@mail.gmail.com>

On Jan 19, 2014 6:49 PM, "Keith Winston" <keithwins at gmail.com> wrote:
>
> Well, as usual thanks for all this, it's really great. I'd worked out
> that it was a distinction between iterators and iterables, though I'm
> going to Oscar's description a few more times: most of it made sense,
> but there are subtleties.
>
> For example, this from the Python 3.3 tutorial:
>
> We say such an object is iterable [referring to "range"], that is,
> suitable as a target for functions and constructs that expect
> something from which they can obtain successive items until the supply
> is exhausted. We have seen that the for statement is such an iterator.
> The function list() is another; it creates lists from iterables:
>
> Now, everything we've said thus far would not have led me to believe
> that one would call the for statement an iterator... is this just
> very, very loose use of the term (in the Python documentation!), or am
> I still missing something biggish?

I think that's just an editing mistake. If you replace the word "iterator"
with "construct" then it makes sense: We have seen that the for statement
is such a construct.

Oscar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140119/9400fb37/attachment.html>

From keithwins at gmail.com  Sun Jan 19 20:22:40 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 19 Jan 2014 14:22:40 -0500
Subject: [Tutor] iterators
In-Reply-To: <CAHVvXxQyJnt5J5VtxagY-fgyH8MenMtM-myj59PdBRVjHCKHXA@mail.gmail.com>
References: <CAO5ffbYVRssVw_EvqnOq7wCi59sPY4z_+6pwsZmEpxzZeaJ94w@mail.gmail.com>
 <CAMw+j7KEOm=84VazDu1icGTC91z52iPBVhyS5oAuE33U2CastQ@mail.gmail.com>
 <CACL+1atv0CNwNvdjdkLtMpFSrLpV70P1DEexsrv5zxE7j2MQJQ@mail.gmail.com>
 <CAO5ffbb19XUPfaxoCXapeg=1e0ehqU0sQEV69CwbqrNhrh0FMA@mail.gmail.com>
 <52DBCB29.8000209@gmail.com>
 <CAHVvXxT0Hz4cGAZu-dDOshtb3r=DiYa9rjLUzSSuyZiCa7SoVQ@mail.gmail.com>
 <lbh02b$uv2$1@ger.gmane.org>
 <CAO5ffbY6Ln4U02U-hPejcrn5vT4UXvHh8b1fkJmwSh9OoJ7C-Q@mail.gmail.com>
 <CAHVvXxQyJnt5J5VtxagY-fgyH8MenMtM-myj59PdBRVjHCKHXA@mail.gmail.com>
Message-ID: <CAO5ffbZp2uHMro_84xf7S8NmR4SCc-h1pZcEvE7B34j2vfHCOA@mail.gmail.com>

On Sun, Jan 19, 2014 at 2:02 PM, Oscar Benjamin
<oscar.j.benjamin at gmail.com> wrote:
> I think that's just an editing mistake. If you replace the word "iterator"
> with "construct" then it makes sense: We have seen that the for statement is
> such a construct.

Fair enough. Thanks. But I think that it underlines the ease with
which the language is used loosely, which does get confusing quickly
when one is still putting together the concepts. I really appreciated
your lengthy post distinguishing iterators from iterables, and I'm
going to go back over it someday that I'm not sick and I have a spare
neuron or two.


-- 
Keith

From keithwins at gmail.com  Sun Jan 19 20:18:54 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 19 Jan 2014 14:18:54 -0500
Subject: [Tutor] Python as Teaching Language
Message-ID: <CAO5ffbaueda7k_tpeWHQBUMrGGDp3Y+wJTX7cvu5YHYYxxwK6A@mail.gmail.com>

On Sun, Jan 19, 2014 at 11:55 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> It has reached the point that I'm back to looking for a new teaching
> language. In Python 3 the decision has clearly been made to focus on
> supporting Python's role as a professional software engineering language
> at the expense of being a successor to ABC or for use in CP4E etc.
> That's a fair enough decision but it does mean Python is no longer the
> easiest option for non Comp Sci beginners. It's not worse than the others
> but it's no longer clearly superior. (IMHO at least! )
>
> But what else is there? that's the problem.... :-(

Hi Alan, since this is off-topic from it's original thread, but I
wanted to respond to it, I popped it into a new thread, I hope you
don't mind (original was subject "iterators").

I can imagine what you mean about a teaching language, and while I
don't 1) teach CS or 2) know Python like you do... AND I don't know
the alternatives... it still feels like the cleanest, most
user-friendly language I've ever worked with. Anyway, there's
something to be said for letting novices play with real tools: instead
of coming to the end of their one-semester computer class feeling like
they just played with legos, they can feel like they got some (minor)
feel for building a house.

An interesting question is, what's the goal (for those students,
probably the majority in a required comp sci course) who aren't going
to do a lot of programming in the future ? I can think of a few: help
people expand/develop/reflect on their ability to think in various
ways; depressurize fear around programming/computers; give them a leg
up in approaching the vast range of computer-supported tools in many
fields... Anyway, I'm sorta loving this language, and it feels like a
decent way "in" to all of those goals.

There are two caveats: one is, without this tutor list (and to a
lesser extent, perhaps because I've relied on this so much), other
online resources (stack overflow, the Python IRC channels, etc), it
would be much harder to make sense of. But those are there, and don't
seem in immediate danger of disappearing.

And the second... the documentation. I really want to love the
documentation, but I can't. I can't maneuver through it hardly at all
(if I'm trying to find something in the documentation, I almost always
search it from Google), it often doesn't give any examples in the
places I want them, and assumes an understanding I don't have at a
given moment. I'm SO GRATEFUL to all the people who have contributed
to the language, including the documentation, and don't imagine I
could do better, I just notice that I haven't figured out how to make
it work for me.

Now, to a large degree this is not the documentations' fault: I forget
things I just read 10s ago, and then I'll charge off to learn a topic
far more advanced than I'm reasonably ready for. I have an iterative
learning process which involves not understanding a disconcerting
amount of what's in front of me. I don't actually think it's optimal,
but I literally can't stand (what feels like) the slow, plodding
forward approach that is the alternative generally offered. I think
there is often a mismatch between teaching structures/approaches, and
peoples (very personal, often ill-understood and ill-developed)
learning styles.

The other thing I wonder about is how to make the learning process
more interactive/social: that is, so many of the questions that (even
more novice than me) people bring here are things like error statement
meanings, etc. In many cases IMO, the first 10 minutes of frustration
around something like that can be enough to leave a lasting bad taste.
I've gotten some very fast responses around here, and immediate ones
on the IRC (which I've only used a little): I believe quick feedback
to be crucial to the learning process, and yet we are often trained,
in school and elsewhere, to smoulder in frustration around things we
don't know yet, I believe (or to just give up and feel stupid)... I
don't know whether social platforms will translate to a greater
readiness to seek help in order to really learn, or just to learn to
fill in the blanks faster/"cheat" better. Teaching is hard.

And a last note on feedback: having the interpreter available is a
definite plus for Python, though learning to disassemble one's
confusion into little pieces that you can test methodically is hard.
But another good skill...

Sorry for the length.

Keith

From keithwins at gmail.com  Sun Jan 19 20:34:13 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 19 Jan 2014 14:34:13 -0500
Subject: [Tutor] string indexing
In-Reply-To: <lbgupa$gme$1@ger.gmane.org>
References: <CAD0YXfVLg-ZtY5LYpOEMTuhT83nRYA7G8zMKTEJqyDu5m2RtWQ@mail.gmail.com>
 <lbgupa$gme$1@ger.gmane.org>
Message-ID: <CAO5ffbbxWunKCSJL5nRLrL+_0pH5QfyrtpNk-7B36AiOURjkcg@mail.gmail.com>

On Sun, Jan 19, 2014 at 11:33 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>>>> help(''.find)
> Help on built-in function find:

Erm, getting what you want from help can be work.

Help(find)  #  doesn't work at all.

What Alan did above was create an empty string, by using two single
quotes next to each other ('', not to be confused with a single double
quote, "), and then seek Help on it's method "find" (methods are
accessed by following an object, in this case the empty string, with a
period, and the method name... in actual use there would be further
parenthesis, but for Help you don't use them)... hence

Help(''.find)

Also, Alan's really right on getting used to playing with bits and
pieces at the >>> prompt, you'll be amazed at how much you can do
there. Just don't try to write lengthy programs there, save those as
files and edit them separately.


-- 
Keith

From breamoreboy at yahoo.co.uk  Sun Jan 19 20:53:37 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 19 Jan 2014 19:53:37 +0000
Subject: [Tutor] string indexing
In-Reply-To: <CAO5ffbbxWunKCSJL5nRLrL+_0pH5QfyrtpNk-7B36AiOURjkcg@mail.gmail.com>
References: <CAD0YXfVLg-ZtY5LYpOEMTuhT83nRYA7G8zMKTEJqyDu5m2RtWQ@mail.gmail.com>
 <lbgupa$gme$1@ger.gmane.org>
 <CAO5ffbbxWunKCSJL5nRLrL+_0pH5QfyrtpNk-7B36AiOURjkcg@mail.gmail.com>
Message-ID: <lbhafr$dv8$1@ger.gmane.org>

On 19/01/2014 19:34, Keith Winston wrote:
> On Sun, Jan 19, 2014 at 11:33 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>>>>> help(''.find)
>> Help on built-in function find:
>
> Erm, getting what you want from help can be work.
>
> Help(find)  #  doesn't work at all.
>

How would Python know whether you want find for gettext, mmap, str, 
xml.etree.ElementTree.Element or xml.etree.ElementTree.ElementTree? 
Those are the ones listed in the Windows compiled help file for Python 
3.3.  You could of course have your own find methods or functions, and 
have yet more from third party libraries.

-- 
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 Jan 19 21:45:26 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 20:45:26 +0000
Subject: [Tutor] Python as Teaching Language
In-Reply-To: <CAO5ffbaueda7k_tpeWHQBUMrGGDp3Y+wJTX7cvu5YHYYxxwK6A@mail.gmail.com>
References: <CAO5ffbaueda7k_tpeWHQBUMrGGDp3Y+wJTX7cvu5YHYYxxwK6A@mail.gmail.com>
Message-ID: <lbhdgp$f8l$1@ger.gmane.org>

On 19/01/14 19:18, Keith Winston wrote:
> On Sun, Jan 19, 2014 at 11:55 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>> It has reached the point that I'm back to looking for a new teaching
>> language. ...
>>
>> But what else is there? that's the problem.... :-(
>
> Hi Alan, since this is off-topic from it's original thread, but I
> wanted to respond to it, I popped it into a new thread, I hope you
> don't mind (original was subject "iterators").

Not at all, I probably should have done that myself.

> I can imagine what you mean about a teaching language, and while I
> don't 1) teach CS or 2) know Python like you do... AND I don't know
> the alternatives... it still feels like the cleanest, most
> user-friendly language I've ever worked with.

I agree although I don't teach CS and don't consider myself a Python 
guru by any means, but I have been programming for 40 years in
over 20 languages so I do know a bit about the alternatives! :-)

> something to be said for letting novices play with real tools: instead
> of coming to the end of their one-semester computer class feeling like
> they just played with legos, they can feel like they got some (minor)
> feel for building a house.

Absolutely, and that's why I first chose Python for my tutor.
I needed a language that students could go away and actually
use for real work - unlike Logo, or even Lisp and Smalltalk.
(I know you can do real work in all of those but they are
hardly mainstream, and the leap from learning to practicality
is quite big IMHO)

> An interesting question is, what's the goal (for those students,
> probably the majority in a required comp sci course) who aren't going
> to do a lot of programming in the future?

I hope CS students will be doing a lot of programming! :-)
But the target for my tutor was that group who had no formal
CS training, and indeed no math training beyond high school,
but needed to program to achieve their objectives. Think
IT operations staff or sys admins or even non CS academics
doing stats etc (This was pre R of course...)

So I needed to be able to avoid technical concepts and yet
be able to back-fill those concepts when needed. Python did
that in v1 and to a lesser degree in v2. But in V3 too many
of the academic features seem to escape from the shadows and
hit the newbie in the face.

> fields... Anyway, I'm sorta loving this language, and it feels like a
> decent way "in" to all of those goals.

I still love Python as a language for my own use.
In fact I'm currently working on another book just now that's
focused on using Python in practical contexts, but it's not
a pure beginners book. And it would be much harder to write
a pure beginners book now than it was 15 years ago when I
did my first. There is so much more to explain to get quite
basic things done.

> There are two caveats: one is, without this tutor list (and to a
> lesser extent, perhaps because I've relied on this so much), other
> online resources (stack overflow, the Python IRC channels, etc), it
> would be much harder to make sense of. But those are there, and don't
> seem in immediate danger of disappearing.

The internet has changed how people learn. Wikipedia is a fantastic 
resource for the pure theory type stuff and user fora are great for 
practical help - although often with as much bad advice as good! Just 
because something works doesn't make it right! But the days of hunkering 
down with a single text book and bulldozing your way
through are, thankfully, long gone.

> And the second... the documentation. I really want to love the
> documentation, but I can't.

You should try learning C or Fortran from the DEC VAX manuals! :-)
The Python docs are a model of clarity. But you do know how
to read them. They are written for professionals.
One of the primary targets of my tutor was to explain all of
those concepts needed to read the docs and understand them.
In that I was only partially successful.

> (if I'm trying to find something in the documentation, I almost always
> search it from Google),

So does everyone else. Python was created in the internet age.
Search engines were assumed to exist and users were expected to
use them.

> it often doesn't give any examples

Yes thats one area that could be im[proved. The subprocess model is one 
exception. I think it would be great if every module page had an 
accompanying examples page. But no, I'm not volunteering to write
them! :-)

And there's the rub, everything in Python is done by volunteers.
Who wants to spend there day writing examples for a manual page
when they could be writing real code?
Getting volunteers to document Open Source projects is always a 
challenge. Python is better served than many. Commercial projects
hire professional Technical Authors to wrie the docs and thus
tend to be of much higher quality. But you often pay as much
for the docs as for the software!

> learning process which involves not understanding a disconcerting
> amount of what's in front of me.... the slow, plodding
> forward approach that is the alternative generally offered.

You are not alone. I'm of the slow plodding variety, but many people 
prefer the Dive In approach. But I *hate* doing things I don't 
understand first. (I always read the manual for things I buy before 
switching them on...or at least the section up to where it tells you how 
to switch it on! :-)

> more novice than me) people bring here are things like error statement
> meanings, etc. In many cases IMO, the first 10 minutes of frustration
> around something like that can be enough to leave a lasting bad taste.

Yes, and it's in those error statements that beginners hit the
under-belly of Python. iterators and range objects etc are fine
and you can ignore them most of the time. But if a newbie gets
an error message referring to range objects or iterators and
they don't know what it means it freaks them out! tracebacks
are great for programmers but absolutely horrendous for
normal users.

I have one friend who got a fairly innocuous traceback from
a program I wrote for her and she immediately switched off
her PC and refused to turn it on again until I came over
to confirm that the message was harmless (2 days later as
it happened). (Blue screens of death on Windows have the
same affect which I assume is why Microsoft seem to have
replaced them in Win8 with a totally bland purple screen
of death that just says something like 'It's broken, start
again'...)

> And a last note on feedback: having the interpreter available is a
> definite plus for Python, though learning to disassemble one's
> confusion into little pieces that you can test methodically is hard.

Yes, and another reason I chose Python. I first learned to program at
high school, in BASIC and later Pascal, on a University mainframe.
We punched code into a paper tape and posted it to the University
who posted back the results 3 days later. ('Missing semi-colon: line 5')
This was not an ideal learning environment! (But it sure made you
check your syntax! :-)

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Sun Jan 19 21:50:30 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 20:50:30 +0000
Subject: [Tutor] string indexing
In-Reply-To: <lbhafr$dv8$1@ger.gmane.org>
References: <CAD0YXfVLg-ZtY5LYpOEMTuhT83nRYA7G8zMKTEJqyDu5m2RtWQ@mail.gmail.com>
 <lbgupa$gme$1@ger.gmane.org>
 <CAO5ffbbxWunKCSJL5nRLrL+_0pH5QfyrtpNk-7B36AiOURjkcg@mail.gmail.com>
 <lbhafr$dv8$1@ger.gmane.org>
Message-ID: <lbhdq9$iln$1@ger.gmane.org>

On 19/01/14 19:53, Mark Lawrence wrote:
> On 19/01/2014 19:34, Keith Winston wrote:

>> Erm, getting what you want from help can be work.
>>
>> Help(find)  #  doesn't work at all.
>>
>
> How would Python know whether you want find for gettext, mmap, str,
> xml.etree.ElementTree.Element or xml.etree.ElementTree.ElementTree?

Absolutely, but a newbie doesn't even guess that more than one find 
would exist. Or even that there would need to be more than one.
It's the same word so why doesn't it just work for everything?!
After all len() seems to do it that way...

That's why help() can be hard work, as Keith says, it's not always
obvious to beginners what to ask for help with.

My bad for not making that clear in my original post...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From eryksun at gmail.com  Sun Jan 19 21:59:49 2014
From: eryksun at gmail.com (eryksun)
Date: Sun, 19 Jan 2014 15:59:49 -0500
Subject: [Tutor] Naming variables
In-Reply-To: <52DBDF56.9090005@gmail.com>
References: <52DAC607.6040406@ncf.ca> <52DBD1E0.5000601@gmail.com>
 <lbglok$jfg$1@ger.gmane.org> <52DBDF56.9090005@gmail.com>
Message-ID: <CACL+1asVjWScTtcKCmgAadBaPe3TSpNSa8hKu-UqaNAi9bbyyg@mail.gmail.com>

On Sun, Jan 19, 2014 at 9:21 AM, spir <denis.spir at gmail.com> wrote:
> I guess (not sure) python optimises access of dicts used as scopes (also of
> object attributes) by interning id-strings and thus beeing able to replace
> them by hash values already computed once for interning, or other numeric

A string object caches its hash, but initially it isn't computed (-1).
On the `dict` lookup fast path, you have a cached hash, where the
string wasn't probed to a different table index by a hash collision,
and the string is interned with the same address (CPython ID) as the
key in the table.

CPython setattr is implemented by calling PyObject_SetAttr, which
interns the name. The string will be used by subsequently interned
strings. Code objects intern strings, but those will already have been
instantiated for the module, and we're dealing with dynamic strings
here like `"year" + str(1900)`. That leaves dynamic code that you
compile/exec.

    years = type('Years', (), {})
    setattr(years, 'year' + str(1900), [])
    s1 = next(s for s in vars(years) if s == 'year1900')

Compile a code object containing the string 'year1900' as a constant:

    code = compile('"year1900"', '<string>', 'exec')
    s2 = next(s for s in code.co_consts if s == 'year1900')

The code object interned the string constant because it's all name
characters (ASCII letters, numbers, and underscore):

    >>> s2 is s1
    True

You could also call sys.intern to get the interned string, but it
isn't worth the cost of the call each time:

    >>> s3 = 'year' + str(1900)
    >>> s3 is s1
    False
    >>> s4 = sys.intern(s3)
    >>> s4 is s1
    True

Thankfully a dict with only string keys uses an efficient equality
comparison, so all of this is really a moot point:

http://hg.python.org/cpython/file/3.3/Objects/stringlib/eq.h

From christian.h.alexander at gmail.com  Sun Jan 19 22:59:58 2014
From: christian.h.alexander at gmail.com (Christian Alexander)
Date: Sun, 19 Jan 2014 16:59:58 -0500
Subject: [Tutor] Understanding Classes
Message-ID: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>

Hello Tutorians,

Looked all over the net for class tutorials
Unable to understand the "self" argument
Attempting to visual classes

I have searched high and low, for easy to follow tutorials regarding
classes.  Although I grok the general concept of classes,  I am unable to
visually understand what exactly "self" does, or why it is even necessary.
 It seems very "magic" to me.  Also I am having the most difficult with the
"__init__()" method in classes, and why that is also required.  Keep in
mind that I am a visual person (maybe I should have been a graphic
designer), therefore most programming concepts flow irritatingly slow for
me.

-- 
Regards,

Christian Alexander
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140119/c0a60465/attachment.html>

From sunithanc at gmail.com  Mon Jan 20 00:36:18 2014
From: sunithanc at gmail.com (SM)
Date: Sun, 19 Jan 2014 18:36:18 -0500
Subject: [Tutor] Question on os.popen
Message-ID: <CAOeFuMSKDCQz1-pDzXrBPuNLnzEW=0Xy0dzUYr+7GzwaZYYbxg@mail.gmail.com>

Hello,
I am using os.popen repeatedly to run Unix shell commands within my Python
program. To be more specific, I am running in a loop which could iterate as
many times as there are lines in an input file - in this example, close to
150 iterations. Each loop has two calls to os.popen.
It works fine for the first few loops and it stops with the following error
message:

IOError: [Errno 4] Interrupted system call

I read about os.popen in
http://docs.python.org/2/library/subprocess.html#subprocess.Popen and used
the "buffer" argument to specify 4096 as the buffer size: os.popen(command,
"r", 4096)

This time it probably ran for a few more iterations than before and stopped
with the same error message. This time it also output the following
messages:

IOError: [Errno 4] Interrupted system call
Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)
Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)
Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)

It always seems to error at the following line:
"part2 = f.read()" in the code-snippet below, after a few iterations. Does
popen use any system resources that need to be closed/released after each
execution? I didn't find any such information in the document though.

        for i in range(0, length):
            if (self.fiDictList[i]['filename'] == filename):

               <snip>
                mmls_cmd = "mmls -i " + imgtype +" "+image +" | grep
\"02:\""
                # f = os.popen(mmls_cmd)  <<< Original line
                f = os.popen(mmls_cmd, 'r', 4096)
                part2 = f.read()   # <<<<<< This is where it shows error
after getting here 4 times.
                part2_list = part2.split()
                part2_start = part2_list[2]
                <snip>
                if (redirect_file == True):
                    icat_cmd = "icat -o "+part2_start+ " "+ image + " " +
self.fiDictList[i]['inode'] + ' > ' + outfile
                    print(">> D: Executing iCAT command: ", icat_cmd)
                    f2 = os.popen(icat_cmd)

                else:
                    <snip>
                return

I am not sure where I am going wrong. Isn't the way I am reading the
popen's output correct? But if so, why does it work for the first few
iterations? Any tips appreciated.

Thanks, in advance.
-SM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140119/2d9e1946/attachment-0001.html>

From alan.gauld at btinternet.com  Mon Jan 20 00:50:59 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sun, 19 Jan 2014 23:50:59 +0000
Subject: [Tutor] Understanding Classes
In-Reply-To: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
References: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
Message-ID: <lbhocn$vg3$1@ger.gmane.org>

On 19/01/14 21:59, Christian Alexander wrote:
> Looked all over the net for class tutorials
> Unable to understand the "self" argument
> Attempting to visual classes

If you read my OOP tutorial there is a section there specifically about 
self.

And the v3 tutor includes an introduction to the formal visualisation
technique for OOP called UML. The diagrams illustrating the designs may 
help.

http://www.alan-g.me.uk/l2p/tutclass.htm

> I have searched high and low, for easy to follow tutorials regarding
> classes.  Although I grok the general concept of classes,

Do you also grok the concept of objects?
Classes on their own are fairly useless (unless you are using Java)
it is only when you create a universe of objects from those classes that 
they become useful.

If you can repeat to us your understanding of classes and their 
relationship with objects that will help us understand your
level and shape our responses accordingly.

> to visually understand what exactly "self" does, or why it is even
> necessary.  It seems very "magic" to me.

When you define a class you define the data (attributes) that
the class instances will have. Each instance will have a copy of the 
data defined in the __init__() method.
You also define a set of operations or methods that are associated
with the class. Those methods are shared by the instances.

Note the difference. Instances get a copy of the attributes
but they all share the methods.

Thus when you invoke a method on an instance the instance relays that 
call to the class. For the class to know which instance is being 
operated on, and for the method to be able to access the correct 
instance's data it needs a reference to the instance. That reference
is typically called 'self' or 'this'. (In some languages it's fixed
but in Python self is only a convention, you can use any name you like).

You can make the call to the class explicit and it will still work.
See below:

# define a class
class MyClass:
     def __init__(self,x): self.x = x
     def myMethod(self): print(self.x)

# create some instances
ObjA = MyClass(2)
ObjB = MyClass(4)
ObjC = MyClass(6)

# send some messages/call methods
objA.myMethod()       # call from the instance
MyClass.myMethod(ObjB)  # call explicitly to the class
objC.myMethod()      # direct again

All 3 calls do the same thing except the middle one
passes the object identifier directly to the class
whereas the first and last both do that internally
within the object structure.

> difficult with the "__init__()" method in classes,
 > and why that is also required.

It is not *required* as such. You can create a class
without an init but it's unusual.

When you create an instance of a class it creates a
data structure in memory referenced by the name of
the instance. But that structure is empty, it has
no data. So to populate the data for the instances
you must initialize it. That's what __init__() does.
It takes the arguments you provide and applies them
to the instance along with any static data definitions
you may define.

In the example we create an instance variable, x,
within the instances and assign the value of the
argument passed to init. Like any other method the
actual code lives in the class so we could initialize
it by calling init like so:

MyClass.__init__(objC, 66)

which is almost the same as doing:

objC = MyClass(66)

The difference is that the first case requires the object ObjC
to already exist, the second example creates a new instance and
then calls init on that instance.

> Keep in mind that I am a visual person (maybe I should have
> been a graphic designer), therefore most programming concepts flow
> irritatingly slow for me.

Most programming concepts have visual representations,
its just that program code being text tends to lead programmers
to be verbally based. But algorithms, state machines, logic, data 
structures, GUIs, formal requirements and OOP all have well
established visual representations, and in many cases they
are formalized so that, with the right tools, you can
create code purely visually.

If the above doesn't clarify things, and I suspect it won't
entirely, then please do express your understanding so far
in your own words and we'll try to clarify things from there.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From keithwins at gmail.com  Mon Jan 20 01:19:46 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sun, 19 Jan 2014 19:19:46 -0500
Subject: [Tutor] string indexing
In-Reply-To: <lbhdq9$iln$1@ger.gmane.org>
References: <CAD0YXfVLg-ZtY5LYpOEMTuhT83nRYA7G8zMKTEJqyDu5m2RtWQ@mail.gmail.com>
 <lbgupa$gme$1@ger.gmane.org>
 <CAO5ffbbxWunKCSJL5nRLrL+_0pH5QfyrtpNk-7B36AiOURjkcg@mail.gmail.com>
 <lbhafr$dv8$1@ger.gmane.org> <lbhdq9$iln$1@ger.gmane.org>
Message-ID: <CAO5ffbZfZmJA3Ex5j6aDJ9K_qGRxu=p6tw3FxDZAa4R242=hbw@mail.gmail.com>

On Sun, Jan 19, 2014 at 3:50 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>> How would Python know whether you want find for gettext, mmap, str,
>> xml.etree.ElementTree.Element or xml.etree.ElementTree.ElementTree?
>
>
> Absolutely, but a newbie doesn't even guess that more than one find would
> exist. Or even that there would need to be more than one.

That's exactly it. I'm just getting to the point of being able to
understand how much I don't know, and (I'm only a little embarrassed
to admit) Alan's empty-string example was an "ah-ha" moment for me. I
expect Help will be a great deal more useful now (of course, as I type
that I realize I could have used the class name, help(str.find),
instead of an impromptu instance. Another little ah-ha). And of
course, the instant I understood all that, the point that Mark made
became obvious. But I didn't see it before.


-- 
Keith

From alan.gauld at btinternet.com  Mon Jan 20 02:20:20 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Jan 2014 01:20:20 +0000
Subject: [Tutor] Question on os.popen
In-Reply-To: <CAOeFuMSKDCQz1-pDzXrBPuNLnzEW=0Xy0dzUYr+7GzwaZYYbxg@mail.gmail.com>
References: <CAOeFuMSKDCQz1-pDzXrBPuNLnzEW=0Xy0dzUYr+7GzwaZYYbxg@mail.gmail.com>
Message-ID: <lbhtk8$fjt$1@ger.gmane.org>

On 19/01/14 23:36, SM wrote:

> I read about os.popen in
> http://docs.python.org/2/library/subprocess.html#subprocess.Popen

This doesn't answer the question but I'm curious.
If you read about os.popen in the subprocess module docs why did
you use it? The subprocess module replaces all the os.popen calls
with the generally superior subprocess.Popen class.

Now, I don't know if using subprocess instead of os would fix
things in this case but it seems an odd choice? I'm curious why
you chose to go with os.popen?

BTW you don't tell us which OS you are using (or which Python
version), that may be pertinent to the answer. I'm assuming
it's some variant of *nix but which one?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From sunithanc at gmail.com  Mon Jan 20 05:00:14 2014
From: sunithanc at gmail.com (SM)
Date: Sun, 19 Jan 2014 23:00:14 -0500
Subject: [Tutor] Question on os.popen
In-Reply-To: <lbhtk8$fjt$1@ger.gmane.org>
References: <CAOeFuMSKDCQz1-pDzXrBPuNLnzEW=0Xy0dzUYr+7GzwaZYYbxg@mail.gmail.com>
 <lbhtk8$fjt$1@ger.gmane.org>
Message-ID: <CAOeFuMSKTcfJ2t1PwM=b4m=yJfhby7snGGDCrmA=qrOkwB634Q@mail.gmail.com>

Hi Alan,
Thanks for your reply.
My answer to why I am using os.popen could be a lame one - I have used it
extensively in various places before and it has been working well and so
was hung up on using it. Now I replaced it by subprocess.check_output with
appropriate parameters and it seems to be working. Does that mean this is
one of the limitations of os.popen? I am not sure.
Sorry for not giving details on the OS and python version I am using:
Ubuntu and Python3.
Thanks,
SM


On Sun, Jan 19, 2014 at 8:20 PM, Alan Gauld <alan.gauld at btinternet.com>wrote:

> On 19/01/14 23:36, SM wrote:
>
>  I read about os.popen in
>> http://docs.python.org/2/library/subprocess.html#subprocess.Popen
>>
>
> This doesn't answer the question but I'm curious.
> If you read about os.popen in the subprocess module docs why did
> you use it? The subprocess module replaces all the os.popen calls
> with the generally superior subprocess.Popen class.
>
> Now, I don't know if using subprocess instead of os would fix
> things in this case but it seems an odd choice? I'm curious why
> you chose to go with os.popen?
>
> BTW you don't tell us which OS you are using (or which Python
> version), that may be pertinent to the answer. I'm assuming
> it's some variant of *nix but which one?
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140119/5b5bb634/attachment.html>

From eryksun at gmail.com  Mon Jan 20 05:33:46 2014
From: eryksun at gmail.com (eryksun)
Date: Sun, 19 Jan 2014 23:33:46 -0500
Subject: [Tutor] Question on os.popen
In-Reply-To: <CAOeFuMSKDCQz1-pDzXrBPuNLnzEW=0Xy0dzUYr+7GzwaZYYbxg@mail.gmail.com>
References: <CAOeFuMSKDCQz1-pDzXrBPuNLnzEW=0Xy0dzUYr+7GzwaZYYbxg@mail.gmail.com>
Message-ID: <CACL+1avKNFbE+TuAwUpkz=kZMSSDngJZX_Wp7cpWCaq1=tBjpA@mail.gmail.com>

On Sun, Jan 19, 2014 at 6:36 PM, SM <sunithanc at gmail.com> wrote:
>
> This time it probably ran for a few more iterations than before and stopped
> with the same error message. This time it also output the following
> messages:
>
> IOError: [Errno 4] Interrupted system call
> Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)
> Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)
> Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not found)

I can't help with these (NTFS?) Attribute errors from "The Sleuth Kit"
digital forensics tools.

In Python 3.3, `IOError` is an alias for `OSError`, and EINTR (i.e.
errno.errorcode[4]) is exposed directly as `InterruptedError`. So you
must be running a previous version. I see you're using `print` as a
function, so I'll guess you're using 3.2.

In 3.2, `os.popen` is implemented via `subprocess.Popen`:

http://hg.python.org/cpython/file/cef745775b65/Lib/os.py#l776

For example, it uses the following for 'r' mode:

    proc = subprocess.Popen(cmd,
                            shell=True,
                            stdout=subprocess.PIPE,
                            bufsize=buffering)
   return _wrap_close(io.TextIOWrapper(proc.stdout), proc)

If you're sticking to `os.popen`, you'll need to retry the read in
case of an interrupted system call.

I recommend you switch to `Popen` directly and call `communicate`.
This retries reading `stdout` using the helper function
`_eintr_retry_call`:

http://hg.python.org/cpython/file/cef745775b65/Lib/subprocess.py#l452

    def _eintr_retry_call(func, *args):
        while True:
            try:
                return func(*args)
            except (OSError, IOError) as e:
                if e.errno == errno.EINTR:
                    continue
                raise

More simply, use `subprocess.check_output`, which calls `communicate`
for you. You can pass `shell=True` if you really need it.

From davea at davea.name  Mon Jan 20 05:42:13 2014
From: davea at davea.name (Dave Angel)
Date: Sun, 19 Jan 2014 23:42:13 -0500 (EST)
Subject: [Tutor] Question on os.popen
References: <CAOeFuMSKDCQz1-pDzXrBPuNLnzEW=0Xy0dzUYr+7GzwaZYYbxg@mail.gmail.com>
 <lbhtk8$fjt$1@ger.gmane.org>
 <CAOeFuMSKTcfJ2t1PwM=b4m=yJfhby7snGGDCrmA=qrOkwB634Q@mail.gmail.com>
Message-ID: <lbi9ad$unk$1@ger.gmane.org>

 SM <sunithanc at gmail.com> Wrote in message:
> Sorry for not giving details on the OS and python version I am using: Ubuntu and Python3


On Sun, Jan 19, 2014 at 8:20 PM, Alan Gauld <ala
n.gauld at btinternet.com> wrote:
On 19/01/14 23:36, SM wrote:

>> I read about os.popen in
>> http://docs.python.org/2/library/subprocess.html#subprocess.Popen
> 

Please don't top-post.

If you're using Python 3.x, why aren't you using the corresponding
 docs page? In the upper left corner of that page is a dropdown
 you can use to get to 3.3 for example. 

-- 
DaveA


From sunithanc at gmail.com  Mon Jan 20 05:40:07 2014
From: sunithanc at gmail.com (SM)
Date: Sun, 19 Jan 2014 23:40:07 -0500
Subject: [Tutor] Question on os.popen
In-Reply-To: <CACL+1avKNFbE+TuAwUpkz=kZMSSDngJZX_Wp7cpWCaq1=tBjpA@mail.gmail.com>
References: <CAOeFuMSKDCQz1-pDzXrBPuNLnzEW=0Xy0dzUYr+7GzwaZYYbxg@mail.gmail.com>
 <CACL+1avKNFbE+TuAwUpkz=kZMSSDngJZX_Wp7cpWCaq1=tBjpA@mail.gmail.com>
Message-ID: <CAOeFuMR_uJmjca54wXmUZROZD3ySkxwLHt-7h6bQZQu15dNU-w@mail.gmail.com>

Eryksun: Thanks for your reply. Yes, as I mentioned in my reply to Allen, I
used subprocess.check_output and it worked for me.
-SM


On Sun, Jan 19, 2014 at 11:33 PM, eryksun <eryksun at gmail.com> wrote:

> On Sun, Jan 19, 2014 at 6:36 PM, SM <sunithanc at gmail.com> wrote:
> >
> > This time it probably ran for a few more iterations than before and
> stopped
> > with the same error message. This time it also output the following
> > messages:
> >
> > IOError: [Errno 4] Interrupted system call
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
>
> I can't help with these (NTFS?) Attribute errors from "The Sleuth Kit"
> digital forensics tools.
>
> In Python 3.3, `IOError` is an alias for `OSError`, and EINTR (i.e.
> errno.errorcode[4]) is exposed directly as `InterruptedError`. So you
> must be running a previous version. I see you're using `print` as a
> function, so I'll guess you're using 3.2.
>
> In 3.2, `os.popen` is implemented via `subprocess.Popen`:
>
> http://hg.python.org/cpython/file/cef745775b65/Lib/os.py#l776
>
> For example, it uses the following for 'r' mode:
>
>     proc = subprocess.Popen(cmd,
>                             shell=True,
>                             stdout=subprocess.PIPE,
>                             bufsize=buffering)
>    return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
>
> If you're sticking to `os.popen`, you'll need to retry the read in
> case of an interrupted system call.
>
> I recommend you switch to `Popen` directly and call `communicate`.
> This retries reading `stdout` using the helper function
> `_eintr_retry_call`:
>
> http://hg.python.org/cpython/file/cef745775b65/Lib/subprocess.py#l452
>
>     def _eintr_retry_call(func, *args):
>         while True:
>             try:
>                 return func(*args)
>             except (OSError, IOError) as e:
>                 if e.errno == errno.EINTR:
>                     continue
>                 raise
>
> More simply, use `subprocess.check_output`, which calls `communicate`
> for you. You can pass `shell=True` if you really need it.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140119/76de55d4/attachment.html>

From sunithanc at gmail.com  Mon Jan 20 05:51:31 2014
From: sunithanc at gmail.com (SM)
Date: Sun, 19 Jan 2014 23:51:31 -0500
Subject: [Tutor] Question on os.popen
In-Reply-To: <lbi9ad$unk$1@ger.gmane.org>
References: <CAOeFuMSKDCQz1-pDzXrBPuNLnzEW=0Xy0dzUYr+7GzwaZYYbxg@mail.gmail.com>
 <lbhtk8$fjt$1@ger.gmane.org>
 <CAOeFuMSKTcfJ2t1PwM=b4m=yJfhby7snGGDCrmA=qrOkwB634Q@mail.gmail.com>
 <lbi9ad$unk$1@ger.gmane.org>
Message-ID: <CAOeFuMS3jKpOjJdvmEzGTBC=eRv4YCZYbGK_vaSRYmM0P9wbZA@mail.gmail.com>

> In the upper left corner of that page is a dropdown you can use to get to
3.3 for example.

Thanks for that info.


On Sun, Jan 19, 2014 at 11:42 PM, Dave Angel <davea at davea.name> wrote:

>  SM <sunithanc at gmail.com> Wrote in message:
> > Sorry for not giving details on the OS and python version I am using:
> Ubuntu and Python3
>
>
> On Sun, Jan 19, 2014 at 8:20 PM, Alan Gauld <ala
> n.gauld at btinternet.com> wrote:
> On 19/01/14 23:36, SM wrote:
>
> >> I read about os.popen in
> >> http://docs.python.org/2/library/subprocess.html#subprocess.Popen
> >
>
> Please don't top-post.
>
> If you're using Python 3.x, why aren't you using the corresponding
>  docs page? In the upper left corner of that page is a dropdown
>  you can use to get to 3.3 for example.
>
> --
> DaveA
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140119/6bd28f47/attachment.html>

From christian.h.alexander at gmail.com  Mon Jan 20 01:55:39 2014
From: christian.h.alexander at gmail.com (Christian Alexander)
Date: Sun, 19 Jan 2014 19:55:39 -0500
Subject: [Tutor] Understanding Classes
In-Reply-To: <lbhocn$vg3$1@ger.gmane.org>
References: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
 <lbhocn$vg3$1@ger.gmane.org>
Message-ID: <CABSj3_6dxn=CYNaazpTjpHyTZgu2yc8gmM4vjgP=ir-ZBqj7Jw@mail.gmail.com>

I would first like to state two things, those being that I am a horrible
writer as well as explaining things, but Ill try my absolute best.
 Everything python is an object.  Strings, integers, lists, so on and so
forth.  In regards to classes and their relativity towards objects, I am at
complete standstill.  However, I understand that classes are parallel to
that of a blueprint, but that is unfortunately where the buck stops.

On Sun, Jan 19, 2014 at 6:50 PM, Alan Gauld <alan.gauld at btinternet.com>wrote:

> On 19/01/14 21:59, Christian Alexander wrote:
>
>> Looked all over the net for class tutorials
>> Unable to understand the "self" argument
>> Attempting to visual classes
>>
>
> If you read my OOP tutorial there is a section there specifically about
> self.
>
> And the v3 tutor includes an introduction to the formal visualisation
> technique for OOP called UML. The diagrams illustrating the designs may
> help.
>
> http://www.alan-g.me.uk/l2p/tutclass.htm
>
>
>  I have searched high and low, for easy to follow tutorials regarding
>> classes.  Although I grok the general concept of classes,
>>
>
> Do you also grok the concept of objects?
> Classes on their own are fairly useless (unless you are using Java)
> it is only when you create a universe of objects from those classes that
> they become useful.
>
> If you can repeat to us your understanding of classes and their
> relationship with objects that will help us understand your
> level and shape our responses accordingly.
>
>
>  to visually understand what exactly "self" does, or why it is even
>> necessary.  It seems very "magic" to me.
>>
>
> When you define a class you define the data (attributes) that
> the class instances will have. Each instance will have a copy of the data
> defined in the __init__() method.
> You also define a set of operations or methods that are associated
> with the class. Those methods are shared by the instances.
>
> Note the difference. Instances get a copy of the attributes
> but they all share the methods.
>
> Thus when you invoke a method on an instance the instance relays that call
> to the class. For the class to know which instance is being operated on,
> and for the method to be able to access the correct instance's data it
> needs a reference to the instance. That reference
> is typically called 'self' or 'this'. (In some languages it's fixed
> but in Python self is only a convention, you can use any name you like).
>
> You can make the call to the class explicit and it will still work.
> See below:
>
> # define a class
> class MyClass:
>     def __init__(self,x): self.x = x
>     def myMethod(self): print(self.x)
>
> # create some instances
> ObjA = MyClass(2)
> ObjB = MyClass(4)
> ObjC = MyClass(6)
>
> # send some messages/call methods
> objA.myMethod()       # call from the instance
> MyClass.myMethod(ObjB)  # call explicitly to the class
> objC.myMethod()      # direct again
>
> All 3 calls do the same thing except the middle one
> passes the object identifier directly to the class
> whereas the first and last both do that internally
> within the object structure.
>
>
>  difficult with the "__init__()" method in classes,
>>
> > and why that is also required.
>
> It is not *required* as such. You can create a class
> without an init but it's unusual.
>
> When you create an instance of a class it creates a
> data structure in memory referenced by the name of
> the instance. But that structure is empty, it has
> no data. So to populate the data for the instances
> you must initialize it. That's what __init__() does.
> It takes the arguments you provide and applies them
> to the instance along with any static data definitions
> you may define.
>
> In the example we create an instance variable, x,
> within the instances and assign the value of the
> argument passed to init. Like any other method the
> actual code lives in the class so we could initialize
> it by calling init like so:
>
> MyClass.__init__(objC, 66)
>
> which is almost the same as doing:
>
> objC = MyClass(66)
>
> The difference is that the first case requires the object ObjC
> to already exist, the second example creates a new instance and
> then calls init on that instance.
>
>
>  Keep in mind that I am a visual person (maybe I should have
>> been a graphic designer), therefore most programming concepts flow
>> irritatingly slow for me.
>>
>
> Most programming concepts have visual representations,
> its just that program code being text tends to lead programmers
> to be verbally based. But algorithms, state machines, logic, data
> structures, GUIs, formal requirements and OOP all have well
> established visual representations, and in many cases they
> are formalized so that, with the right tools, you can
> create code purely visually.
>
> If the above doesn't clarify things, and I suspect it won't
> entirely, then please do express your understanding so far
> in your own words and we'll try to clarify things from there.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> 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
>



-- 
Regards,

Christian Alexander
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140119/8892cc45/attachment-0001.html>

From matbioinfo at gmail.com  Mon Jan 20 08:37:03 2014
From: matbioinfo at gmail.com (rahmad akbar)
Date: Mon, 20 Jan 2014 08:37:03 +0100
Subject: [Tutor] string indexing
Message-ID: <CAD0YXfXeW=Hwyj2KU217TVgBJj_oNP1rfiDXrcGgW9rj=MkN9g@mail.gmail.com>

Spir and Peter, thanks for the specifics, super helpful. Alan, super thanks
for the general advice, you guys are awesome!!




On Mon, Jan 20, 2014 at 5:34 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: Understanding Classes (Alan Gauld)
>    2. Re: string indexing (Keith Winston)
>    3. Re: Question on os.popen (Alan Gauld)
>    4. Re: Question on os.popen (SM)
>    5. Re: Question on os.popen (eryksun)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Sun, 19 Jan 2014 23:50:59 +0000
> From: Alan Gauld <alan.gauld at btinternet.com>
> To: tutor at python.org
> Subject: Re: [Tutor] Understanding Classes
> Message-ID: <lbhocn$vg3$1 at ger.gmane.org>
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>
> On 19/01/14 21:59, Christian Alexander wrote:
> > Looked all over the net for class tutorials
> > Unable to understand the "self" argument
> > Attempting to visual classes
>
> If you read my OOP tutorial there is a section there specifically about
> self.
>
> And the v3 tutor includes an introduction to the formal visualisation
> technique for OOP called UML. The diagrams illustrating the designs may
> help.
>
> http://www.alan-g.me.uk/l2p/tutclass.htm
>
> > I have searched high and low, for easy to follow tutorials regarding
> > classes.  Although I grok the general concept of classes,
>
> Do you also grok the concept of objects?
> Classes on their own are fairly useless (unless you are using Java)
> it is only when you create a universe of objects from those classes that
> they become useful.
>
> If you can repeat to us your understanding of classes and their
> relationship with objects that will help us understand your
> level and shape our responses accordingly.
>
> > to visually understand what exactly "self" does, or why it is even
> > necessary.  It seems very "magic" to me.
>
> When you define a class you define the data (attributes) that
> the class instances will have. Each instance will have a copy of the
> data defined in the __init__() method.
> You also define a set of operations or methods that are associated
> with the class. Those methods are shared by the instances.
>
> Note the difference. Instances get a copy of the attributes
> but they all share the methods.
>
> Thus when you invoke a method on an instance the instance relays that
> call to the class. For the class to know which instance is being
> operated on, and for the method to be able to access the correct
> instance's data it needs a reference to the instance. That reference
> is typically called 'self' or 'this'. (In some languages it's fixed
> but in Python self is only a convention, you can use any name you like).
>
> You can make the call to the class explicit and it will still work.
> See below:
>
> # define a class
> class MyClass:
>      def __init__(self,x): self.x = x
>      def myMethod(self): print(self.x)
>
> # create some instances
> ObjA = MyClass(2)
> ObjB = MyClass(4)
> ObjC = MyClass(6)
>
> # send some messages/call methods
> objA.myMethod()       # call from the instance
> MyClass.myMethod(ObjB)  # call explicitly to the class
> objC.myMethod()      # direct again
>
> All 3 calls do the same thing except the middle one
> passes the object identifier directly to the class
> whereas the first and last both do that internally
> within the object structure.
>
> > difficult with the "__init__()" method in classes,
>  > and why that is also required.
>
> It is not *required* as such. You can create a class
> without an init but it's unusual.
>
> When you create an instance of a class it creates a
> data structure in memory referenced by the name of
> the instance. But that structure is empty, it has
> no data. So to populate the data for the instances
> you must initialize it. That's what __init__() does.
> It takes the arguments you provide and applies them
> to the instance along with any static data definitions
> you may define.
>
> In the example we create an instance variable, x,
> within the instances and assign the value of the
> argument passed to init. Like any other method the
> actual code lives in the class so we could initialize
> it by calling init like so:
>
> MyClass.__init__(objC, 66)
>
> which is almost the same as doing:
>
> objC = MyClass(66)
>
> The difference is that the first case requires the object ObjC
> to already exist, the second example creates a new instance and
> then calls init on that instance.
>
> > Keep in mind that I am a visual person (maybe I should have
> > been a graphic designer), therefore most programming concepts flow
> > irritatingly slow for me.
>
> Most programming concepts have visual representations,
> its just that program code being text tends to lead programmers
> to be verbally based. But algorithms, state machines, logic, data
> structures, GUIs, formal requirements and OOP all have well
> established visual representations, and in many cases they
> are formalized so that, with the right tools, you can
> create code purely visually.
>
> If the above doesn't clarify things, and I suspect it won't
> entirely, then please do express your understanding so far
> in your own words and we'll try to clarify things from there.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.flickr.com/photos/alangauldphotos
>
>
>
> ------------------------------
>
> Message: 2
> Date: Sun, 19 Jan 2014 19:19:46 -0500
> From: Keith Winston <keithwins at gmail.com>
> Cc: Python Tutor Mailing List <tutor at python.org>
> Subject: Re: [Tutor] string indexing
> Message-ID:
>         <CAO5ffbZfZmJA3Ex5j6aDJ9K_qGRxu=p6tw3FxDZAa4R242=
> hbw at mail.gmail.com>
> Content-Type: text/plain; charset=ISO-8859-1
>
> On Sun, Jan 19, 2014 at 3:50 PM, Alan Gauld <alan.gauld at btinternet.com>
> wrote:
> >> How would Python know whether you want find for gettext, mmap, str,
> >> xml.etree.ElementTree.Element or xml.etree.ElementTree.ElementTree?
> >
> >
> > Absolutely, but a newbie doesn't even guess that more than one find would
> > exist. Or even that there would need to be more than one.
>
> That's exactly it. I'm just getting to the point of being able to
> understand how much I don't know, and (I'm only a little embarrassed
> to admit) Alan's empty-string example was an "ah-ha" moment for me. I
> expect Help will be a great deal more useful now (of course, as I type
> that I realize I could have used the class name, help(str.find),
> instead of an impromptu instance. Another little ah-ha). And of
> course, the instant I understood all that, the point that Mark made
> became obvious. But I didn't see it before.
>
>
> --
> Keith
>
>
> ------------------------------
>
> Message: 3
> Date: Mon, 20 Jan 2014 01:20:20 +0000
> From: Alan Gauld <alan.gauld at btinternet.com>
> To: tutor at python.org
> Subject: Re: [Tutor] Question on os.popen
> Message-ID: <lbhtk8$fjt$1 at ger.gmane.org>
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>
> On 19/01/14 23:36, SM wrote:
>
> > I read about os.popen in
> > http://docs.python.org/2/library/subprocess.html#subprocess.Popen
>
> This doesn't answer the question but I'm curious.
> If you read about os.popen in the subprocess module docs why did
> you use it? The subprocess module replaces all the os.popen calls
> with the generally superior subprocess.Popen class.
>
> Now, I don't know if using subprocess instead of os would fix
> things in this case but it seems an odd choice? I'm curious why
> you chose to go with os.popen?
>
> BTW you don't tell us which OS you are using (or which Python
> version), that may be pertinent to the answer. I'm assuming
> it's some variant of *nix but which one?
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.flickr.com/photos/alangauldphotos
>
>
>
> ------------------------------
>
> Message: 4
> Date: Sun, 19 Jan 2014 23:00:14 -0500
> From: SM <sunithanc at gmail.com>
> To: Alan Gauld <alan.gauld at btinternet.com>
> Cc: "tutor at python.org" <tutor at python.org>
> Subject: Re: [Tutor] Question on os.popen
> Message-ID:
>         <CAOeFuMSKTcfJ2t1PwM=b4m=yJfhby7snGGDCrmA=
> qrOkwB634Q at mail.gmail.com>
> Content-Type: text/plain; charset="iso-8859-1"
>
> Hi Alan,
> Thanks for your reply.
> My answer to why I am using os.popen could be a lame one - I have used it
> extensively in various places before and it has been working well and so
> was hung up on using it. Now I replaced it by subprocess.check_output with
> appropriate parameters and it seems to be working. Does that mean this is
> one of the limitations of os.popen? I am not sure.
> Sorry for not giving details on the OS and python version I am using:
> Ubuntu and Python3.
> Thanks,
> SM
>
>
> On Sun, Jan 19, 2014 at 8:20 PM, Alan Gauld <alan.gauld at btinternet.com
> >wrote:
>
> > On 19/01/14 23:36, SM wrote:
> >
> >  I read about os.popen in
> >> http://docs.python.org/2/library/subprocess.html#subprocess.Popen
> >>
> >
> > This doesn't answer the question but I'm curious.
> > If you read about os.popen in the subprocess module docs why did
> > you use it? The subprocess module replaces all the os.popen calls
> > with the generally superior subprocess.Popen class.
> >
> > Now, I don't know if using subprocess instead of os would fix
> > things in this case but it seems an odd choice? I'm curious why
> > you chose to go with os.popen?
> >
> > BTW you don't tell us which OS you are using (or which Python
> > version), that may be pertinent to the answer. I'm assuming
> > it's some variant of *nix but which one?
> >
> > --
> > Alan G
> > Author of the Learn to Program web site
> > http://www.alan-g.me.uk/
> > 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
> >
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <
> http://mail.python.org/pipermail/tutor/attachments/20140119/5b5bb634/attachment-0001.html
> >
>
> ------------------------------
>
> Message: 5
> Date: Sun, 19 Jan 2014 23:33:46 -0500
> From: eryksun <eryksun at gmail.com>
> To: SM <sunithanc at gmail.com>
> Cc: "tutor at python.org" <tutor at python.org>
> Subject: Re: [Tutor] Question on os.popen
> Message-ID:
>         <CACL+1avKNFbE+TuAwUpkz=kZMSSDngJZX_Wp7cpWCaq1=
> tBjpA at mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> On Sun, Jan 19, 2014 at 6:36 PM, SM <sunithanc at gmail.com> wrote:
> >
> > This time it probably ran for a few more iterations than before and
> stopped
> > with the same error message. This time it also output the following
> > messages:
> >
> > IOError: [Errno 4] Interrupted system call
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
> > Attribute not found in file (tsk_fs_attrlist_get: Attribute 128 not
> found)
>
> I can't help with these (NTFS?) Attribute errors from "The Sleuth Kit"
> digital forensics tools.
>
> In Python 3.3, `IOError` is an alias for `OSError`, and EINTR (i.e.
> errno.errorcode[4]) is exposed directly as `InterruptedError`. So you
> must be running a previous version. I see you're using `print` as a
> function, so I'll guess you're using 3.2.
>
> In 3.2, `os.popen` is implemented via `subprocess.Popen`:
>
> http://hg.python.org/cpython/file/cef745775b65/Lib/os.py#l776
>
> For example, it uses the following for 'r' mode:
>
>     proc = subprocess.Popen(cmd,
>                             shell=True,
>                             stdout=subprocess.PIPE,
>                             bufsize=buffering)
>    return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
>
> If you're sticking to `os.popen`, you'll need to retry the read in
> case of an interrupted system call.
>
> I recommend you switch to `Popen` directly and call `communicate`.
> This retries reading `stdout` using the helper function
> `_eintr_retry_call`:
>
> http://hg.python.org/cpython/file/cef745775b65/Lib/subprocess.py#l452
>
>     def _eintr_retry_call(func, *args):
>         while True:
>             try:
>                 return func(*args)
>             except (OSError, IOError) as e:
>                 if e.errno == errno.EINTR:
>                     continue
>                 raise
>
> More simply, use `subprocess.check_output`, which calls `communicate`
> for you. You can pass `shell=True` if you really need it.
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> https://mail.python.org/mailman/listinfo/tutor
>
>
> ------------------------------
>
> End of Tutor Digest, Vol 119, Issue 91
> **************************************
>



-- 
many thanks
mat
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140120/d820cfe0/attachment-0001.html>

From riekanddoug at gmail.com  Mon Jan 20 02:16:42 2014
From: riekanddoug at gmail.com (Doug and Riekie Dorman)
Date: Sun, 19 Jan 2014 17:16:42 -0800
Subject: [Tutor] 4.7.5
Message-ID: <52DC78FA.5010808@gmail.com>

I think I may have found a bug:

>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>pairs.sort(key=lambda  pair:  pair[1])
>>>pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

Should be:

>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>pairs.sort(key=lambda  pairs:  pairs[1])
>>>pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

I have increased the size of the two s's to show the problem.

Doug


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140119/e3a0bd4d/attachment.html>

From alan.gauld at btinternet.com  Mon Jan 20 10:33:29 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Jan 2014 09:33:29 +0000
Subject: [Tutor] Understanding Classes
In-Reply-To: <CABSj3_6dxn=CYNaazpTjpHyTZgu2yc8gmM4vjgP=ir-ZBqj7Jw@mail.gmail.com>
References: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
 <lbhocn$vg3$1@ger.gmane.org>
 <CABSj3_6dxn=CYNaazpTjpHyTZgu2yc8gmM4vjgP=ir-ZBqj7Jw@mail.gmail.com>
Message-ID: <lbiqgt$f48$1@ger.gmane.org>

On 20/01/14 00:55, Christian Alexander wrote:
> I would first like to state two things, those being that I am a horrible
> writer as well as explaining things, but Ill try my absolute best.
>   Everything python is an object.  Strings, integers, lists, so on and
> so forth.  In regards to classes and their relativity towards objects, I
> am at complete standstill.

OK, we need to backup a little.

Objects are the individual instances of data that we work with.
This individual strings like 'foo' and 'hello' are objects.
Strings in general are a class. 'foo' and 'bar' are instances of that 
class, or objects of that class. (instance and object are almost synonymous)

Similarly for integers. 3,5,97 and 123456789 are all instances
of the integer class.

Of course these are built in classes of object so you don't see an 
explicit class defined anywhere. But classes that you define are just 
like those built in types. You define the structure and behaviour in the 
class and create instances of it to work with as objects.

> However, I understand that classes are
> parallel to that of a blueprint,

Yes, they define what the objects will look like, what data and what 
methods they contain. But to use those objects you have to instantiate 
them and its there that the usage varies slightly from the built in types:

For built in string type objects you do this

mystring = 'a new string object'

But if String were a user defined class you'd need to do this:

mystring = String('a user defined string object')

ie. you'd 'call' the class name with the data arguments needed.
In fact in Python you can explicitly call str() if you really
want to, missing it out is a convenience.

After that initial object creation you would use mystring identically 
regardless of whether it was user defined or built in. So we can call 
methods of the class using the instance like:

mystring.upper()
mystring.split()

etc

Do you follow things so far? It's important to understand the usage of 
classes and objects before we start worrying about the internal
details.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From breamoreboy at yahoo.co.uk  Mon Jan 20 10:39:41 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Mon, 20 Jan 2014 09:39:41 +0000
Subject: [Tutor] 4.7.5
In-Reply-To: <52DC78FA.5010808@gmail.com>
References: <52DC78FA.5010808@gmail.com>
Message-ID: <lbiqsn$j3b$1@ger.gmane.org>

On 20/01/2014 01:16, Doug and Riekie Dorman wrote:
> I think I may have found a bug:
>
>>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>>pairs.sort(key=lambda  pair:  pair[1])
>>>>pairs
> [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
>
> Should be:
>
>>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>>pairs.sort(key=lambda  pairs:  pairs[1])
>>>>pairs
> [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
>
> I have increased the size of the two s's to show the problem.
>
> Doug
>

What has the name you've given your lambda parameter got to do with the 
name of your list?

-- 
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  Mon Jan 20 10:35:23 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Jan 2014 09:35:23 +0000
Subject: [Tutor] string indexing
In-Reply-To: <CAD0YXfXeW=Hwyj2KU217TVgBJj_oNP1rfiDXrcGgW9rj=MkN9g@mail.gmail.com>
References: <CAD0YXfXeW=Hwyj2KU217TVgBJj_oNP1rfiDXrcGgW9rj=MkN9g@mail.gmail.com>
Message-ID: <lbiqke$f48$2@ger.gmane.org>

On 20/01/14 07:37, rahmad akbar wrote:
> Spir and Peter, thanks for the specifics, super helpful. Alan, super
> thanks for the general advice, you guys are awesome!!

You are welcome, but please don't post an entire digest just to say 
thanks. It uses up bandwidth and storage unnecessarily and some
folks pay by the byte... Delete the unnecessary content.

Thanks,

Alan G.




From oscar.j.benjamin at gmail.com  Mon Jan 20 11:41:37 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Mon, 20 Jan 2014 10:41:37 +0000
Subject: [Tutor] Python as Teaching Language
In-Reply-To: <CAO5ffbaueda7k_tpeWHQBUMrGGDp3Y+wJTX7cvu5YHYYxxwK6A@mail.gmail.com>
References: <CAO5ffbaueda7k_tpeWHQBUMrGGDp3Y+wJTX7cvu5YHYYxxwK6A@mail.gmail.com>
Message-ID: <20140120104135.GB2178@gmail.com>

On Sun, Jan 19, 2014 at 02:18:54PM -0500, Keith Winston wrote:
> On Sun, Jan 19, 2014 at 11:55 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> > It has reached the point that I'm back to looking for a new teaching
> > language. In Python 3 the decision has clearly been made to focus on
> > supporting Python's role as a professional software engineering language
> > at the expense of being a successor to ABC or for use in CP4E etc.
> > That's a fair enough decision but it does mean Python is no longer the
> > easiest option for non Comp Sci beginners. It's not worse than the others
> > but it's no longer clearly superior. (IMHO at least! )
> >
> > But what else is there? that's the problem.... :-(
> 
> Hi Alan, since this is off-topic from it's original thread, but I
> wanted to respond to it, I popped it into a new thread, I hope you
> don't mind (original was subject "iterators").

That's the right thing to do. The usual convention is to change the subject
line to "Python as a teaching language [Was: iterators]" so that it's clear
from the subject line that you've spawned a new thread from an existing one.

Alan, next year I will be teaching a new unit for our first-year Engineering
undergrads using Python as an introduction to programming so I've been
thinking about these things quite a lot recently. Any language has features
that you can't use in an intro course: so just leave them out!

If someone wants to spend lots of time learning Python comprehensively then
they can do that later. Thankfully you can do a lot in Python without fully
understanding its "underbelly".

As a case in point I don't plan to teach generators or iterators. I will
probably broach that subject as follows:

In Python there are many types of objects we can loop over with a "for"
statement. We have already seen examples of this with lists and strings e.g.:

>>> a = [4, 2, 5]
>>> for x in a:
...     print(a, 2*a)
4 8
2 4
5 10

Objects that we can loop over are known as "iterable". There are other types
of objects that are not iterable such as ints and floats:

>>> b = 123
>>> for x in b:
...     print(b)
TypeError: 'int' object is not iterable

Note how the error message tells us that this type of object ('int') is not
'iterable'.

We've already seen examples of looping over the lines of a text file. It's
common in other programming languages to write something like:

f = open('myfile.txt')
while True:
    line = f.readline()
    if not line: # empty string when we get to the end of the file
        break
    print(line.upper())  # Do whatever you want with the line here
f.close() # Always close the file when done!!!

Looping over the lines of a file is so common though that Python has a more
convenient version using the fact that a file object is iterable:

f = open('myfile.txt')
for line in f:
    print(line.upper())
f.close()

One other thing that we need to know here is that some iterables (e.g. lists
and strings) can be looped over multiple times whereas file objects can only
be looped over once. If you want to loop over the lines of the file again you
need to re-open the file (or seek back to the beginning).

I would then go on to relate all of the above to list comprehensions. I don't
think I'd bother with talking about iterators/iterables and iter/next except
in a more advanced Python course. In that course I would also cover generators
and other things but for an intro just skip over it.


Oscar

From fomcl at yahoo.com  Mon Jan 20 11:42:57 2014
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Mon, 20 Jan 2014 02:42:57 -0800 (PST)
Subject: [Tutor] when is "pythondontwritebytecode" useful?
Message-ID: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>

Hi,


When is setting a PYTHONDONTWRITEBYTECODE environment variable useful? Or set sys.dont_write_bytecode to True? Or start Python with the -B option?
I know what it does (http://docs.python.org/2/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE), i.e. no pyc or pyo fiules are written, but WHY is that sometimes a good thing? The only useful scenario I can think of is when you don't have write rights to create pyc files but you want to use a package anyway.


Perhaps related: it is possible to import zip files, but no pyc files will be created when you do this. However, I recently opened an EGG file with a zip utility (because I knew egg uses zipimport so it's a zip-like format) and I noticed that there were .pyc files. If the creator of the egg put them there, they'd only be useful if the user uses the exact same Python implementatiopn and version, right? So hoiw can the be there?

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

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140120/b1acd81d/attachment-0001.html>

From alan.gauld at btinternet.com  Mon Jan 20 11:48:16 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Mon, 20 Jan 2014 10:48:16 +0000
Subject: [Tutor] 4.7.5
In-Reply-To: <52DC78FA.5010808@gmail.com>
References: <52DC78FA.5010808@gmail.com>
Message-ID: <lbiut3$3bk$1@ger.gmane.org>

On 20/01/14 01:16, Doug and Riekie Dorman wrote:
> I think I may have found a bug:
>
>>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>>pairs.sort(key=lambda  pair:  pair[1])
>>>>pairs
> [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
>
> Should be:
>
>>>>pairs  =  [(1,  'one'),  (2,  'two'),  (3,  'three'),  (4,  'four')]
>>>>pairs.sort(key=lambda  pairs:  pairs[1])
>>>>pairs
> [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
>
> I have increased the size of the two s's to show the problem.

In plain text that doesn't help. However you seem to be confused about 
what the lambda is doing.

pairs.sort(key = lambda p : p[1])

is the same as

def somefunc(p):
     return p[1]

pairs.sort(key=somefunc)

The parameter to the lambda function is completely separate to the list. 
It's part of the function definition. It takes on whatever
value is passed, in your case it is passed the individual tuples
within the list. The name you use is irrelevant.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From bouncingcats at gmail.com  Mon Jan 20 11:59:02 2014
From: bouncingcats at gmail.com (David)
Date: Mon, 20 Jan 2014 21:59:02 +1100
Subject: [Tutor] Understanding Classes
In-Reply-To: <lbiqgt$f48$1@ger.gmane.org>
References: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
 <lbhocn$vg3$1@ger.gmane.org>
 <CABSj3_6dxn=CYNaazpTjpHyTZgu2yc8gmM4vjgP=ir-ZBqj7Jw@mail.gmail.com>
 <lbiqgt$f48$1@ger.gmane.org>
Message-ID: <CAMPXz=okUsxSkp7Aq+i718XQ76mhYzmss=w70a7_VDA7iTAF3A@mail.gmail.com>

On 20 January 2014 20:33, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 20/01/14 00:55, Christian Alexander wrote:
>>
>> I would first like to state two things, those being that I am a horrible
>> writer as well as explaining things, but Ill try my absolute best.
>>   Everything python is an object.  Strings, integers, lists, so on and
>> so forth.  In regards to classes and their relativity towards objects, I
>> am at complete standstill.
>
> For built in string type objects you do this
>
> mystring = 'a new string object'
>
> But if String were a user defined class you'd need to do this:
>
> mystring = String('a user defined string object')
>
> ie. you'd 'call' the class name with the data arguments needed.
> In fact in Python you can explicitly call str() if you really
> want to, missing it out is a convenience.
>
> After that initial object creation you would use mystring identically
> regardless of whether it was user defined or built in. So we can call
> methods of the class using the instance like:
>
> mystring.upper()
> mystring.split()

And Christian you can experiment with Alan's examples interactively
by running the Python interpreter, for example:

$ python
Python 2.7.3 (default, Jan  2 2013, 16:53:07)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> mystring = 'a new string object'
>>> type(mystring)
<type 'str'>
>>> mystring.upper()
'A NEW STRING OBJECT'
>>> 'another new string'.upper()
'ANOTHER NEW STRING'
>>> 'yet another string'.split()
['yet', 'another', 'string']

>>> exit()

Typing in the first >>> line
>>> mystring = 'a new string object'
creates a string object.

Typing in the next >>> line
>>> type(mystring)
shows that mystring is of type str, which is the built in class for
strings. So the mystring object is an instance created from class str.

Typing in the next line
>>> mystring.upper()
shows that the mystring object possesses a built in method named
upper() that knows how to return an upper case copy of itself.

Typing in the next line
>>> 'another new string'.upper()
shows that any/every string knows how to do the same thing. Because
every string has the same method named upper(). Because every string
instance is created from the str class, and the str class defines
upper(), so every string inherits this method.

Typing in the next line
>>> 'yet another string'.split()
shows that any/every string has a method named split() that knows how
to return a list of individual words in the string. This method is
also defined by the str class, and so is inherited by every string.

> Do you follow things so far?

From oscar.j.benjamin at gmail.com  Mon Jan 20 12:11:54 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Mon, 20 Jan 2014 11:11:54 +0000
Subject: [Tutor] when is "pythondontwritebytecode" useful?
In-Reply-To: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
References: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
Message-ID: <20140120111152.GC2178@gmail.com>

On Mon, Jan 20, 2014 at 02:42:57AM -0800, Albert-Jan Roskam wrote:
> Hi,
> 
> 
> When is setting a PYTHONDONTWRITEBYTECODE environment variable useful? Or set sys.dont_write_bytecode to True? Or start Python with the -B option?
> I know what it does (http://docs.python.org/2/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE), i.e. no pyc or pyo fiules are written, but WHY is that sometimes a good thing? The only useful scenario I can think of is when you don't have write rights to create pyc files but you want to use a package anyway.

If you don't have write permissions then it won't write the byte code files
anyway.

> Perhaps related: it is possible to import zip files, but no pyc files will be created when you do this. However, I recently opened an EGG file with a zip utility (because I knew egg uses zipimport so it's a zip-like format) and I noticed that there were .pyc files. If the creator of the egg put them there, they'd only be useful if the user uses the exact same Python implementatiopn and version, right? So hoiw can the be there?

The .pyc files will be ignored if the versions don't match.

One problem that can occur with the byte-code files is if you try to import
them using different interpreters at different times. So let's say you have a
module that is regularly imported by Python 2.6 and then you also want to use
it in a program that you regularly run with Python 2.7. The two interpreters
will fight each other constantly rewriting and stomping over each other's .pyc
files. You could use the -B option with one of the interpreters to alleviate
this.

Truthfully I've never used the option so I'm just guessing though. And in any
case Python 3 handles the multiple interpreters problem better with its
__pycache__ directory.


Oscar

From denis.spir at gmail.com  Mon Jan 20 12:50:52 2014
From: denis.spir at gmail.com (spir)
Date: Mon, 20 Jan 2014 12:50:52 +0100
Subject: [Tutor] string indexing -- side note, rather OT
In-Reply-To: <CAO5ffbZfZmJA3Ex5j6aDJ9K_qGRxu=p6tw3FxDZAa4R242=hbw@mail.gmail.com>
References: <CAD0YXfVLg-ZtY5LYpOEMTuhT83nRYA7G8zMKTEJqyDu5m2RtWQ@mail.gmail.com>
 <lbgupa$gme$1@ger.gmane.org>
 <CAO5ffbbxWunKCSJL5nRLrL+_0pH5QfyrtpNk-7B36AiOURjkcg@mail.gmail.com>
 <lbhafr$dv8$1@ger.gmane.org> <lbhdq9$iln$1@ger.gmane.org>
 <CAO5ffbZfZmJA3Ex5j6aDJ9K_qGRxu=p6tw3FxDZAa4R242=hbw@mail.gmail.com>
Message-ID: <52DD0D9C.5070203@gmail.com>

On 01/20/2014 01:19 AM, Keith Winston wrote:
> On Sun, Jan 19, 2014 at 3:50 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>>> How would Python know whether you want find for gettext, mmap, str,
>>> xml.etree.ElementTree.Element or xml.etree.ElementTree.ElementTree?
>>
>>
>> Absolutely, but a newbie doesn't even guess that more than one find would
>> exist. Or even that there would need to be more than one.
>
> That's exactly it. I'm just getting to the point of being able to
> understand how much I don't know, and (I'm only a little embarrassed
> to admit) Alan's empty-string example was an "ah-ha" moment for me. I
> expect Help will be a great deal more useful now (of course, as I type
> that I realize I could have used the class name, help(str.find),
> instead of an impromptu instance. Another little ah-ha). And of
> course, the instant I understood all that, the point that Mark made
> became obvious. But I didn't see it before.

Side note, rather OT:

It is apparently very hard to share the perspective of novices once one gets 
used to features to the point they have become easy. It seems, in fact, often 
much harder for programmers than other people (I suspect this is because 
programmers, or "geeks", are often more "autistic" so to say). Obviously, a 
talented footballer (soccer) does not consider juggling with a ball (using only 
feet/head) easy for novices!

Some programmers, of which I consider they have a "pedagogic spirit", 
nevertheless are obviously skilled in that, whatever their expertise level. I 
think this is just "normal" human skill (sociability, in fact) but our way of 
life alters or distorts it.

Denis

From pierre.dagenais at ncf.ca  Mon Jan 20 16:49:35 2014
From: pierre.dagenais at ncf.ca (Pierre Dagenais)
Date: Mon, 20 Jan 2014 10:49:35 -0500
Subject: [Tutor] ValueError: could not convert string to float: '13,2'
In-Reply-To: <lbg1ug$jag$1@ger.gmane.org>
References: <52C2CC62.60300@ncf.ca>
 <CAO5ffbagFJTxt2YuTDsA-H5SYuvdKzROG3DG5SSO_2gYG98FCA@mail.gmail.com>
 <52DAC2C4.7090501@ncf.ca> <lbg1ug$jag$1@ger.gmane.org>
Message-ID: <52DD458F.6010008@ncf.ca>

Not very elegant, but it'll work. I don't suppose there is a
>> function for determining the number of digits after the decimal, is it?
> 
> It looks like you are trying to avoid rounding errors in decimal arithmetic. 
> You might be interested in Python's decimal.Decimal type then.

That's right, I had never heard of decimal.Decimal. I'll check it up.
> 
>> Also, anybody knows the maximum and/or minimum integer python will accept?
> 
> Integers in Python (*) are "unlimited"
> 
>>>> 10**1000 -1
> 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
 99
>  99999999
>  99                                  
> 
> In practice the amount of available memory will be the limit, but you are 
> unlikely to reach that.
> 
> (*) Python 2 had int and long where values that could not represented by 
> machine integers were automatically propagated to long. In Python 3 the int 
> and long have been united as int.

Thank you very much,

From denis.spir at gmail.com  Mon Jan 20 22:20:53 2014
From: denis.spir at gmail.com (spir)
Date: Mon, 20 Jan 2014 22:20:53 +0100
Subject: [Tutor] Understanding Classes
In-Reply-To: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
References: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
Message-ID: <52DD9335.6080604@gmail.com>

On 01/19/2014 10:59 PM, Christian Alexander wrote:
> Hello Tutorians,
>
> Looked all over the net for class tutorials
> Unable to understand the "self" argument
> Attempting to visual classes
>
> I have searched high and low, for easy to follow tutorials regarding
> classes.  Although I grok the general concept of classes,  I am unable to
> visually understand what exactly "self" does, or why it is even necessary.
>   It seems very "magic" to me.  Also I am having the most difficult with the
> "__init__()" method in classes, and why that is also required.  Keep in
> mind that I am a visual person (maybe I should have been a graphic
> designer), therefore most programming concepts flow irritatingly slow for
> me.

Imagine that for an app you had to define 2 persons p1 & p2 (maybe game 
characters for instance). In an imaginary programming language, a definition of 
p1 could look like this:

     p1 = {name="Maria", age=33}     # no good python code

This would be a composite piece of data, made of 2 fields (attributes, 
properties...). In python there is no such generic type Object or Composite to 
which such data as p1 could belong. You must define a custom type (class) for 
them, eg:

     class Person: pass

Now, you can have p1 of type Person, which is written as if you would call the 
type Person, like a func, to make a new person (this is close to what happens):

     p1 = Person()

Then, one can define fields on it:

     p1.name = "Maria"
     p1.age = 33
     print(p1.name, p1.age)

We could do the same thing for p2:

     p2 = Person()
     p2.name = "paulo"
     p2.age = 22
     print(p2.name, p2.age)

Now, say persons are supposed to do things, and all can do the same things. To 
define something all persons can do, you would define it on their class (this is 
the second purpose of a class), eg:

     class Person:
         def salute (self):
             print ("Hello, my name is " + self.name +
                 " and I am " + str(self.age) " years old.")

As you can see, this method uses the attributes 'name' & 'age' we manually 
defined on both p1 & p2. Then, how does the method, which is defined on the 
type, not on individual objects, know where to find these attributes? You are 
right to say there is some magic at play here. Let us use the method first, 
before explaining:

     p1.salute()
     p2.salute()

[Copy-paste & run all this code.] On the first call, we ask the method 'salute' 
to operate on p1, and it writes p1's name & age. Same for p2. Inside the method, 
the attributes are searched on the weird param called 'self'. This is just what 
happens: when calling a method, the object on which it operates is assigned to 
the parameter self. 'self' is just a name for 
the-object-on-which-this-method-operates-now. When it operates on p1, self is 
p1, thus attributes are searched on p1; same for p2. We need some placeholder 
because the method is defined on the type and works for any object of this type 
(any "instance"). [We can define a method on p1 which works on p1 only. Maybe 
try it.]

Finally, if we define a whole range of persons that way, it is annoying to set 
all attributes manually. We could define a method, say 'def_attrs', to be called 
at startup. But python has a specially dedicated method for that, which we don't 
even need to call explicitely, named '__init__'. We will use it to set person 
attributes:

     class Person:
         def __init__ (self, name, age):
             self.name = name
             self.age  = age
         def salute (self):
             print ("Hello, my name is " + self.name +
                 " and I am " + str(self.age) " years old.")

(yes, init methods typically are as stupid as this; too bad python does not do 
the mechanical job automagically) And this is used like this:

     p1 = Person("maria", 33)    # no need to call __init__ explicitely
     p1.salute()
     p2 = Person("paulo", 22)    # ditto
     p2.salute()

denis

From eryksun at gmail.com  Mon Jan 20 23:08:07 2014
From: eryksun at gmail.com (eryksun)
Date: Mon, 20 Jan 2014 17:08:07 -0500
Subject: [Tutor] when is "pythondontwritebytecode" useful?
In-Reply-To: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
References: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
Message-ID: <CACL+1auxjUkuA=8Uq3jEo-bh=vrKAbDAJv625yHjEUTH7FWacw@mail.gmail.com>

On Mon, Jan 20, 2014 at 5:42 AM, Albert-Jan Roskam <fomcl at yahoo.com> wrote:
>
> When is setting a PYTHONDONTWRITEBYTECODE environment variable useful? Or
> set sys.dont_write_bytecode to True? Or start Python with the -B option?
> I know what it does
> (http://docs.python.org/2/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE),
> i.e. no pyc or pyo fiules are written, but WHY is that sometimes a good
> thing? The only useful scenario I can think of is when you don't have write
> rights to create pyc files but you want to use a package anyway.

The bug tracker can provide insight into why a given feature exists,
or why it's implemented a certain way:

Issue 602345: option for not writing .py[co] files
http://bugs.python.org/issue602345

> However, I recently opened an EGG file with a zip utility (because I knew
> egg uses zipimport so it's a zip-like format) and I noticed that there
> were .pyc files.

Eggs are a binary distribution format. They contain byte-compiled .pyc
files and extension modules. There's even an option to exclude .py
source files. The filename should indicate the Python version and
platform.

Loading extension modules directly from an egg depends on the
pkg_resources module from setuptools. The modules are extracted to a
local cache directory. On Windows the default cache directory is
"%APPDATA%\Python-Eggs", else it uses "~/.python-eggs". You can
customize this with the environment variable PYTHON_EGG_CACHE.

From stareq13 at yahoo.com  Mon Jan 20 21:51:25 2014
From: stareq13 at yahoo.com (S Tareq)
Date: Mon, 20 Jan 2014 20:51:25 +0000 (GMT)
Subject: [Tutor] how run it on python 3
Message-ID: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>

this is the coding that i am trying to run it on python 3.3. the original coding was made on python 2.7 however i have made some changes to the coding to make it work on python 3.3. the changes that i have made ?on brackets and raw_input to input. the coding does not load the external file ans says invalid syntax . please help me thank You very much. ??

the changed coding:?
# Import statements
import random
import datetime
#Arrays to store the definitions and keywords read from the file
keywords=[];
definition=[];
correctAnswer=[];
#Counter for the wrong Answer and counter of number of definition in
correctAnswerCounter=0?
wrongAnswer=0;
counter=0;
# Taking User input for accepting the file name to be read
filename = ("keywords.txt")
#Reading the file from start to the end
for line in open(filename,'r').readlines():
? ? if(counter%2==0):
? ? ? ? keywords.append(line);
? ? ? ? counter=counter+1;
? ? ? ? correctAnswer.append(0)
? ? else:
? ? ? ? definition.append(line);
? ? ? ? keys=[];
? ? ? ? keys=line.split(" ");
? ? ? ? counter=counter+1;
# Running two while loops to make the pattern recursive
while True:
# Starting the time for quiz and also, creating variables to make sure that same sequences and answers are not repeated
? ? a = datetime.datetime.now().replace(microsecond=0)
? ? prevWord=0
? ? prevSeq=0
? ? # While loop to run the code till each answer is correctly answered
? ? while correctAnswer.count(2)!=(counter/2):
? ? ? ? #While loop to generate an different random number from one the generated previously
? ? ? ? while True: ? ? ? ?
? ? ? ? ? ? word=random.randint(0,(counter/2)-1)
? ? ? ? ? ? if(correctAnswer[word]!=2):
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? if(prevWord==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? # Displaying the new keyword each time.
? ? ? ? print ("Please Select the number which is the correct definition of the word:") ,keywords[word]
? ? ? ? #Generating an new sequence each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? sequences =random.randint(0,2)
? ? ? ? ? ? if(prevSeq==sequences):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswer=random.randint(0,len(correctAnswer)-1)
? ? ? ? ? ? if(incorrectAnswer==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else :
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer ?each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswerSecond=random.randint(0,len(correctAnswer)-1);
? ? ? ? ? ? if (incorrectAnswer==incorrectAnswerSecond):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? if(incorrectAnswerSecond==word):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? # Displaying the options to the user based on the sequence number generated
? ? ? ? if (sequences==0):
? ? ? ? ? ? print ("1."),definition[word]
? ? ? ? ? ? print ("2."),definition[incorrectAnswer]
? ? ? ? ? ? print ("3."),definition[incorrectAnswerSecond]
? ? ? ? elif (sequences==1):
? ? ? ? ? ? print ("1."),definition[incorrectAnswer]
? ? ? ? ? ? print ("2."),definition[incorrectAnswerSecond]
? ? ? ? ? ? print ("3."),definition[word]
? ? ? ? elif (sequences==2):
? ? ? ? ? ? print ("1."),definition[incorrectAnswerSecond]
? ? ? ? ? ? print ("2."),definition[word]
? ? ? ? ? ? print ("3."),definition[incorrectAnswer]
? ? ? ? #Taking the answer from user
? ? ? ? answer = input("Enter the Correct Number between 1 to 3")
? ? ? ? # Assign the seq and word to preseq and word
? ? ? ? prevSeq=sequences
? ? ? ? prevWord=word
? ? ? ? #Checking the answer if they are corret.
? ? ? ? if(0 == sequences):
? ? ? ? ? ? if(answer == "1"):
? ? ? ? ? ? ? ? print ("success")
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print ("Wrong Answer")
? ? ? ? ? ? ? ? print ("Correct Answer: ") ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(1 == sequences):
? ? ? ? ? ? if(answer == "3"):
? ? ? ? ? ? ? ? print ("success")
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print ("Wrong Answer")
? ? ? ? ? ? ? ? print ("Correct Answer: ") ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(2 == sequences):
? ? ? ? ? ? if(answer == "2"):
? ? ? ? ? ? ? ? print ("success")
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print ("Wrong Answer")
? ? ? ? ? ? ? ? print ("Correct Answer: ") ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1
? ? # Stopping the time of the clock
? ? b = datetime.datetime.now().replace(microsecond=0)
? ? # displaying number of wrong answer and total quiz time
? ? print ("Total Number of Wrong Answer:"), wrongAnswer
? ? print ("Total Quiz Time"), (b-a)
? ? print ("Total Number of correct Answer"), correctAnswerCounter
? ? #asking user to reenter
? ? restart= raw_input("Do You want to start the quiz again Yes or No")
? ? if(restart=="no"):
? ? ? ? print ("Thanks for quiz")
? ? ? ? break;
? ? elif(restart==("yes"):
? ? ? ? wrongAnswer=0
? ? ? ? correctAnswerCounter=0;
? ? ? ? correctAnswer=[];
? ? ? ? i=0
? ? ? ? while (i<(counter/2)):
? ? ? ? ? ? i=i+1
? ? ? ? ? ? correctAnswer.append(0)

??
original Coding:
# Import statements
import random
import datetime
#Arrays to store the definitions and keywords read from the file
keywords=[];
definition=[];
correctAnswer=[];
#Counter for the wrong Answer and counter of number of definition in
correctAnswerCounter=0?
wrongAnswer=0;
counter=0;
# Taking User input for accepting the file name to be read
filename= raw_input("Enter the File Name with extension")
#Reading the file from start to the end
for line in open(filename,'r').readlines():
? ? if(counter%2==0):
? ? ? ? keywords.append(line);
? ? ? ? counter=counter+1;
? ? ? ? correctAnswer.append(0)
? ? else:
? ? ? ? definition.append(line);
? ? ? ? keys=[];
? ? ? ? keys=line.split(" ");
? ? ? ? counter=counter+1;
# Running two while loops to make the pattern recursive
while True:
# Starting the time for quiz and also, creating variables to make sure that same sequences and answers are not repeated
? ? a = datetime.datetime.now().replace(microsecond=0)
? ? prevWord=0
? ? prevSeq=0
? ? # While loop to run the code till each answer is correctly answered
? ? while correctAnswer.count(2)!=(counter/2):
? ? ? ? #While loop to generate an different random number from one the generated previously
? ? ? ? while True: ? ? ? ?
? ? ? ? ? ? word=random.randint(0,(counter/2)-1)
? ? ? ? ? ? if(correctAnswer[word]!=2):
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? if(prevWord==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? # Displaying the new keyword each time.
? ? ? ? print "Please Select the number which is the correct definition of the word:" ,keywords[word]
? ? ? ? #Generating an new sequence each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? sequences =random.randint(0,2)
? ? ? ? ? ? if(prevSeq==sequences):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswer=random.randint(0,len(correctAnswer)-1)
? ? ? ? ? ? if(incorrectAnswer==word):
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? else :
? ? ? ? ? ? ? ? break
? ? ? ? #Generating an new incorrect answer ?each time different from previous one
? ? ? ? while True:
? ? ? ? ? ? incorrectAnswerSecond=random.randint(0,len(correctAnswer)-1);
? ? ? ? ? ? if (incorrectAnswer==incorrectAnswerSecond):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? if(incorrectAnswerSecond==word):
? ? ? ? ? ? ? ? continue
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? # Displaying the options to the user based on the sequence number generated
? ? ? ? if (sequences==0):
? ? ? ? ? ? print "1.",definition[word]
? ? ? ? ? ? print "2.",definition[incorrectAnswer]
? ? ? ? ? ? print "3.",definition[incorrectAnswerSecond]
? ? ? ? elif (sequences==1):
? ? ? ? ? ? print "1.",definition[incorrectAnswer]
? ? ? ? ? ? print "2.",definition[incorrectAnswerSecond]
? ? ? ? ? ? print "3.",definition[word]
? ? ? ? elif (sequences==2):
? ? ? ? ? ? print "1.",definition[incorrectAnswerSecond]
? ? ? ? ? ? print "2.",definition[word]
? ? ? ? ? ? print "3.",definition[incorrectAnswer]
? ? ? ? #Taking the answer from user
? ? ? ? answer = raw_input("Enter the Correct Number between 1 to 3")
? ? ? ? # Assign the seq and word to preseq and word
? ? ? ? prevSeq=sequences
? ? ? ? prevWord=word
? ? ? ? #Checking the answer if they are corret.
? ? ? ? if(0 == sequences):
? ? ? ? ? ? if(answer == "1"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(1 == sequences):
? ? ? ? ? ? if(answer == "3"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1;
? ? ? ? elif(2 == sequences):
? ? ? ? ? ? if(answer == "2"):
? ? ? ? ? ? ? ? print "success"
? ? ? ? ? ? ? ? correctAnswer[word]=correctAnswer[word]+1
? ? ? ? ? ? ? ? correctAnswerCounter=correctAnswerCounter+1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "Wrong Answer"
? ? ? ? ? ? ? ? print "Correct Answer: " ,definition[word]
? ? ? ? ? ? ? ? wrongAnswer=wrongAnswer+1
? ? # Stopping the time of the clock
? ? b = datetime.datetime.now().replace(microsecond=0)
? ? # displaying number of wrong answer and total quiz time
? ? print "Total Number of Wrong Answer:", wrongAnswer
? ? print "Total Quiz Time", (b-a)
? ? print "Total Number of correct Answer", correctAnswerCounter
? ? #asking user to reenter
? ? restart= raw_input("Do You want to start the quiz again Yes or No")
? ? if(restart=="No"):
? ? ? ? print "Thanks for quiz"
? ? ? ? break;
? ? elif(restart=="Yes"):
? ? ? ? wrongAnswer=0
? ? ? ? correctAnswerCounter=0;
? ? ? ? correctAnswer=[];
? ? ? ? i=0
? ? ? ? while (i<(counter/2)):
? ? ? ? ? ? i=i+1
? ? ? ? ? ? correctAnswer.append(0)

the text External file (keywords.txt) contains these Keyword and definitions:
cellulose
Tough substance that makes up the cell walls of green plants.
respiration
A chemical reaction that causes energy to be released from glucose.
haemoglobin
A substance which joins to oxygen and carries it round the body in blood.
ventilation
Breathing.
cartilage
Tough and smooth substance covering the ends of bones to protect them.
cytoplasm
Jelly-like part of a cell where chemical reactions happen.
nucleus
Controls what happens inside a cell.
alveoli
Tiny air sacs in the lungs.
amino acids
Produced when proteins are digested.
virus
The smallest type of microbe.
white blood cells
Can engulf bacteria or make antibodies.
photosynthesis
The process of turning carbon dioxide water and light into glucose and oxygen.
stomata
Small holes in the underside of a leaf.
vaccine
Dead or inactive forms of a microorganism.
fibre
A nutrient that cannot be digested.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140120/b47cc908/attachment-0001.html>

From emile at fenx.com  Mon Jan 20 23:55:06 2014
From: emile at fenx.com (Emile van Sebille)
Date: Mon, 20 Jan 2014 14:55:06 -0800
Subject: [Tutor] how run it on python 3
In-Reply-To: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
Message-ID: <lbk9g4$dvj$1@ger.gmane.org>

On 1/20/2014 12:51 PM, S Tareq wrote:

> external file ans says invalid syntax .

The full traceback with the invalid syntax message will provide you the 
specific line where the issue is realized.  Note that the actual error 
my occur elsewhere particularly with mismatched parenthetical 
expressions, but always include the full traceback as that tells us 
where to start looking for the issue.

Emile




From __peter__ at web.de  Tue Jan 21 00:00:52 2014
From: __peter__ at web.de (Peter Otten)
Date: Tue, 21 Jan 2014 00:00:52 +0100
Subject: [Tutor] how run it on python 3
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
Message-ID: <lbk9pp$h23$1@ger.gmane.org>

S Tareq wrote:

> this is the coding that i am trying to run it on python 3.3. the original
> coding was made on python 2.7 however i have made some changes to the
> coding to make it work on python 3.3. the changes that i have made  on
> brackets and raw_input to input. the coding does not load the external
> file ans says invalid syntax . please help me thank You very much.
> 
> the changed coding:

> print ("Please Select the number which is the correct definition of the
> word:") ,keywords[word] #Generating an new sequence each time different
> from previous one while True:

print is a function in Python 3.
Python 2's statement

print "Please select...", keywords[word]

must be spelt

print("Please select...", keywords[word])

You have added the closing parenthesis too early.

But you should not translate your scripts by hand -- there's a tool called 
2to3 that does the legwork for you.




From bran.m.g at gmail.com  Tue Jan 21 00:30:32 2014
From: bran.m.g at gmail.com (Brandon Gardell)
Date: Mon, 20 Jan 2014 16:30:32 -0700
Subject: [Tutor] how run it on python 3 (S Tareq)
Message-ID: <CAKT7xm5q+vhDx5EmXv8DVAoxrNLHc0JLddc0yG6_EAzjcKaydQ@mail.gmail.com>

Tareq,

It'd be nice if you formatted it through upload with gist (
https://gist.github.com/ ) and posted the syntax error you were receiving
as well. Then you wouldn't have to put ?s instead of indents, and we'd be
able to read it better. I believe this is actually recommended in the
mailing list information and rules.

Brandon
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140120/a618dbe3/attachment.html>

From dyoo at hashcollision.org  Tue Jan 21 01:05:20 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Mon, 20 Jan 2014 16:05:20 -0800
Subject: [Tutor] how run it on python 3
In-Reply-To: <lbk9pp$h23$1@ger.gmane.org>
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
 <lbk9pp$h23$1@ger.gmane.org>
Message-ID: <CAGZAPF5bXdhkVYQzNLEStFiv5ZSydKjSWzfSee1upjsHu0CF_w@mail.gmail.com>

> But you should not translate your scripts by hand -- there's a tool called
> 2to3 that does the legwork for you.


S Tareq has asked this question just a few days ago.

    https://mail.python.org/pipermail/tutor/2014-January/099466.html

Most of us here have not yet gone entirely senile yet, so we still remember.


In that thread, we asked the original questioner why they were having
difficulty.  But S Tareq responded in the way I would expect out of an
automated answering machine: that is, not at all.  This is not
encouraging: either he or she did not understand the question, or they
ignored the multiple requests for clarification.


In which case, I can only suggest: please read and respond to what
other people are asking you.  Otherwise, it defeats the purpose of
asking a question: that is, to communicate.

From emile at fenx.com  Tue Jan 21 01:15:42 2014
From: emile at fenx.com (Emile van Sebille)
Date: Mon, 20 Jan 2014 16:15:42 -0800
Subject: [Tutor] how run it on python 3
In-Reply-To: <CAGZAPF5bXdhkVYQzNLEStFiv5ZSydKjSWzfSee1upjsHu0CF_w@mail.gmail.com>
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
 <lbk9pp$h23$1@ger.gmane.org>
 <CAGZAPF5bXdhkVYQzNLEStFiv5ZSydKjSWzfSee1upjsHu0CF_w@mail.gmail.com>
Message-ID: <lbke78$vg7$1@ger.gmane.org>

On 1/20/2014 4:05 PM, Danny Yoo wrote:
> S Tareq has asked this question just a few days ago.
>
>      https://mail.python.org/pipermail/tutor/2014-January/099466.html
>
> Most of us here have not yet gone entirely senile yet, so we still remember.

Speak for yourself! The rest of us are rapidly approaching senility and 
looking forward to it!  You get to meet new people every day and they 
all like you!  :)

> In that thread, we asked the original questioner why they were having
> difficulty.  But S Tareq responded in the way I would expect out of an
> automated answering machine: that is, not at all.  This is not
> encouraging: either he or she did not understand the question, or they
> ignored the multiple requests for clarification.

We're continuing this off-line at the moment and I'm reasonably 
convinced it's not an automated answering machine.

And with any luck future posts won't be quite so diluted...

Emile




> In which case, I can only suggest: please read and respond to what
> other people are asking you.  Otherwise, it defeats the purpose of
> asking a question: that is, to communicate.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



From dyoo at hashcollision.org  Tue Jan 21 01:30:49 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Mon, 20 Jan 2014 16:30:49 -0800
Subject: [Tutor] how run it on python 3
In-Reply-To: <lbke78$vg7$1@ger.gmane.org>
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
 <lbk9pp$h23$1@ger.gmane.org>
 <CAGZAPF5bXdhkVYQzNLEStFiv5ZSydKjSWzfSee1upjsHu0CF_w@mail.gmail.com>
 <lbke78$vg7$1@ger.gmane.org>
Message-ID: <CAGZAPF6qYeMuFcaEhu3D7+AfEc_g=BYW31ychk8qj=vxdiBB9Q@mail.gmail.com>

>> In that thread, we asked the original questioner why they were having
>> difficulty.  But S Tareq responded in the way I would expect out of an
>> automated answering machine: that is, not at all.  This is not
>> encouraging: either he or she did not understand the question, or they
>> ignored the multiple requests for clarification.
>
> We're continuing this off-line at the moment and I'm reasonably convinced
> it's not an automated answering machine.
>
> And with any luck future posts won't be quite so diluted...


Ok.  If you do hear back, please keep the rest of the mailing list
informed.  I was waiting for some kind of response to the thread from
last week:

    https://mail.python.org/pipermail/tutor/2014-January/099591.html

and when threads dangle like that, it feels like an unresolved
cliffhanger.  I do not like cliffhangers.  :P

From breamoreboy at yahoo.co.uk  Tue Jan 21 01:35:05 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Tue, 21 Jan 2014 00:35:05 +0000
Subject: [Tutor] how run it on python 3
In-Reply-To: <CAGZAPF5bXdhkVYQzNLEStFiv5ZSydKjSWzfSee1upjsHu0CF_w@mail.gmail.com>
References: <1390251085.58770.YahooMailNeo@web133103.mail.ir2.yahoo.com>
 <lbk9pp$h23$1@ger.gmane.org>
 <CAGZAPF5bXdhkVYQzNLEStFiv5ZSydKjSWzfSee1upjsHu0CF_w@mail.gmail.com>
Message-ID: <lbkfbk$d6v$1@ger.gmane.org>

On 21/01/2014 00:05, Danny Yoo wrote:
>> But you should not translate your scripts by hand -- there's a tool called
>> 2to3 that does the legwork for you.
>
> S Tareq has asked this question just a few days ago.
>
>      https://mail.python.org/pipermail/tutor/2014-January/099466.html
>
> Most of us here have not yet gone entirely senile yet, so we still remember.
>
> In that thread, we asked the original questioner why they were having
> difficulty.  But S Tareq responded in the way I would expect out of an
> automated answering machine: that is, not at all.  This is not
> encouraging: either he or she did not understand the question, or they
> ignored the multiple requests for clarification.
>
> In which case, I can only suggest: please read and respond to what
> other people are asking you.  Otherwise, it defeats the purpose of
> asking a question: that is, to communicate.
>

Seems more likely that they didn't like being told not to send flaming 
great big screen dumps when a couple of lines cut 'n pasted would have 
been enough.  Which I had to look up, but trying to follow the threads 
on PEPs 460 and 461 was rather hard work and my health isn't the best :(

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

Mark Lawrence


From denis.spir at gmail.com  Tue Jan 21 09:50:43 2014
From: denis.spir at gmail.com (spir)
Date: Tue, 21 Jan 2014 09:50:43 +0100
Subject: [Tutor] Understanding Classes
In-Reply-To: <CABSj3_4tXGdGMJXGYgKW-Aycaxzh3Xy_A2p89V_XF2SwbehG=g@mail.gmail.com>
References: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>	<52DD9335.6080604@gmail.com>
 <CABSj3_4tXGdGMJXGYgKW-Aycaxzh3Xy_A2p89V_XF2SwbehG=g@mail.gmail.com>
Message-ID: <52DE34E3.3030003@gmail.com>

On 01/21/2014 05:20 AM, Christian Alexander wrote:
> Alan,
>
> The concept and purpose of classes is starting to sink in a little bit, but
> I still haven't had my "Ah-ha" moment yet.  I just can't seem to visualize
> the execution of classes, nor am I able to explain to myself how it
> actually works.   For example:
>
>
>      class Person:
>          def __init__ (self, name, age):        # is self just a placeholder
> for  an arbitrary object?  How does __init__ actually work?
>              self.name = name                         # why assign name to
> self.name variable?
>              self.age  = age                               # same as previous
>          def salute (self):                                 # again with the
> self
>              print ("Hello, my name is " + self.name +
>                  " and I am " + str(self.age) + " years old.")

[PLease avoid top-posting, and quote only the parts of the post you actually 
reply to.]

Yes, self is just a placeholder, as I said in the post you reply to. (I used the 
same word.) It is a placeholder for *whatever object it operates on, now*. If 
you call a Person methon on 'x', then x is assigned to self.

We assign name & age tp self, meaning to x, because a person is defined as a 
composite piece of data {name, age}. Read again the very start of my previous 
post, where I wrote the definition of p1, directly, in an imaginary language:

    p1 = {name="Maria", age=33}     # no good python code

This is a programming of a person, as we need. This means, for this application, 
we need a person to be defined by these 2 relevant properties, both of them, and 
nothing more.

__init__ works as if we had programmed that way:

===============
class Person:
     def init (self, name, age):
         self.name = name
         self.age  = age
     def salute (self):
         print ("Hello, my name is " + self.name +
             " and I am " + str(self.age) + " years old.")

p1 = Person()
p1.init("Maria", 33)
p1.salute()
================

except that we don't need to call it. Do you understand the principle of (1) 
defining a function with potential input variables (2) executing it on actual 
input variables? In python the "potential input variables" are called 
"parameters", while "actual input variables" are called "arguments".

There is a similar relation between a class and objects of that class. A class 
defined potential objects, with potential attributes (here name & age); 
"instances" are actual objects of that class with actual attributes.

For the matter, I don't think your difficulties with these notions are related 
to you beeing a visual thinkers: I am, too, and strongly so (and after all, the 
notion of type is firstly visual: think at naive species).

Denis

From asanch505 at hotmail.com  Tue Jan 21 07:18:21 2014
From: asanch505 at hotmail.com (Adriansanchez)
Date: Mon, 20 Jan 2014 23:18:21 -0700
Subject: [Tutor] How to print certain elements
Message-ID: <BLU0-SMTP433730E278FD58756F42933E9A40@phx.gbl>

Hello everyone,
I am newbie to Python and programming in general. My question is, given a list:
X=['washington','adams','jefferson','madison','monroe']
And a string:
Y='washington,adams,jefferson,madison,monroe'

How would I print washington and monroe using   [:]?
How would I print every element but those two names?
Thanks community!
-A-

From christian.h.alexander at gmail.com  Tue Jan 21 05:20:43 2014
From: christian.h.alexander at gmail.com (Christian Alexander)
Date: Mon, 20 Jan 2014 23:20:43 -0500
Subject: [Tutor] Understanding Classes
In-Reply-To: <52DD9335.6080604@gmail.com>
References: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
 <52DD9335.6080604@gmail.com>
Message-ID: <CABSj3_4tXGdGMJXGYgKW-Aycaxzh3Xy_A2p89V_XF2SwbehG=g@mail.gmail.com>

Alan,

The concept and purpose of classes is starting to sink in a little bit, but
I still haven't had my "Ah-ha" moment yet.  I just can't seem to visualize
the execution of classes, nor am I able to explain to myself how it
actually works.   For example:


    class Person:
        def __init__ (self, name, age):        # is self just a placeholder
for  an arbitrary object?  How does __init__ actually work?
            self.name = name                         # why assign name to
self.name variable?
            self.age  = age                               # same as previous
        def salute (self):                                 # again with the
self
            print ("Hello, my name is " + self.name +
                " and I am " + str(self.age) " years old.")


On Mon, Jan 20, 2014 at 4:20 PM, spir <denis.spir at gmail.com> wrote:

> On 01/19/2014 10:59 PM, Christian Alexander wrote:
>
>> Hello Tutorians,
>>
>> Looked all over the net for class tutorials
>> Unable to understand the "self" argument
>> Attempting to visual classes
>>
>> I have searched high and low, for easy to follow tutorials regarding
>> classes.  Although I grok the general concept of classes,  I am unable to
>> visually understand what exactly "self" does, or why it is even necessary.
>>   It seems very "magic" to me.  Also I am having the most difficult with
>> the
>> "__init__()" method in classes, and why that is also required.  Keep in
>> mind that I am a visual person (maybe I should have been a graphic
>> designer), therefore most programming concepts flow irritatingly slow for
>> me.
>>
>
> Imagine that for an app you had to define 2 persons p1 & p2 (maybe game
> characters for instance). In an imaginary programming language, a
> definition of p1 could look like this:
>
>     p1 = {name="Maria", age=33}     # no good python code
>
> This would be a composite piece of data, made of 2 fields (attributes,
> properties...). In python there is no such generic type Object or Composite
> to which such data as p1 could belong. You must define a custom type
> (class) for them, eg:
>
>     class Person: pass
>
> Now, you can have p1 of type Person, which is written as if you would call
> the type Person, like a func, to make a new person (this is close to what
> happens):
>
>     p1 = Person()
>
> Then, one can define fields on it:
>
>     p1.name = "Maria"
>     p1.age = 33
>     print(p1.name, p1.age)
>
> We could do the same thing for p2:
>
>     p2 = Person()
>     p2.name = "paulo"
>     p2.age = 22
>     print(p2.name, p2.age)
>
> Now, say persons are supposed to do things, and all can do the same
> things. To define something all persons can do, you would define it on
> their class (this is the second purpose of a class), eg:
>
>     class Person:
>         def salute (self):
>             print ("Hello, my name is " + self.name +
>                 " and I am " + str(self.age) " years old.")
>
> As you can see, this method uses the attributes 'name' & 'age' we manually
> defined on both p1 & p2. Then, how does the method, which is defined on the
> type, not on individual objects, know where to find these attributes? You
> are right to say there is some magic at play here. Let us use the method
> first, before explaining:
>
>     p1.salute()
>     p2.salute()
>
> [Copy-paste & run all this code.] On the first call, we ask the method
> 'salute' to operate on p1, and it writes p1's name & age. Same for p2.
> Inside the method, the attributes are searched on the weird param called
> 'self'. This is just what happens: when calling a method, the object on
> which it operates is assigned to the parameter self. 'self' is just a name
> for the-object-on-which-this-method-operates-now. When it operates on p1,
> self is p1, thus attributes are searched on p1; same for p2. We need some
> placeholder because the method is defined on the type and works for any
> object of this type (any "instance"). [We can define a method on p1 which
> works on p1 only. Maybe try it.]
>
> Finally, if we define a whole range of persons that way, it is annoying to
> set all attributes manually. We could define a method, say 'def_attrs', to
> be called at startup. But python has a specially dedicated method for that,
> which we don't even need to call explicitely, named '__init__'. We will use
> it to set person attributes:
>
>     class Person:
>         def __init__ (self, name, age):
>             self.name = name
>             self.age  = age
>         def salute (self):
>             print ("Hello, my name is " + self.name +
>                 " and I am " + str(self.age) " years old.")
>
> (yes, init methods typically are as stupid as this; too bad python does
> not do the mechanical job automagically) And this is used like this:
>
>     p1 = Person("maria", 33)    # no need to call __init__ explicitely
>     p1.salute()
>     p2 = Person("paulo", 22)    # ditto
>     p2.salute()
>
> denis
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Regards,

Christian Alexander
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140120/8d143480/attachment.html>

From alan.gauld at btinternet.com  Tue Jan 21 11:04:18 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 21 Jan 2014 10:04:18 +0000
Subject: [Tutor] Understanding Classes
In-Reply-To: <CABSj3_4tXGdGMJXGYgKW-Aycaxzh3Xy_A2p89V_XF2SwbehG=g@mail.gmail.com>
References: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
 <52DD9335.6080604@gmail.com>
 <CABSj3_4tXGdGMJXGYgKW-Aycaxzh3Xy_A2p89V_XF2SwbehG=g@mail.gmail.com>
Message-ID: <lblgml$a3b$1@ger.gmane.org>

On 21/01/14 04:20, Christian Alexander wrote:

>      class Person:
>          def __init__ (self, name, age):        # is self just a
> placeholder for  an arbitrary object?

Yes. If you create say 4 persons, John, Paul, Ringo and George.
When you call any method on those people objects the same code
in the Person class will get executed. So that method code needs some 
way to know which object is being manipulated. That's all that self is, 
a reference to the object currently being worked on.

> How does __init__ actually work?

__init__() is actually just an ordinary metjod like any other.
There is no magic in the method itself. It is a function that takes in 
arhguments (self, name, age in this case) and processes them (stores 
them in the self object).

The magic happens when the Class is instantiated.
So if we create a person object like this:

paul = Person("Paul", 71)

Python first creates a new empty object in memory then passes that 
object to Person.__init() with the arguments (paul, "Paul", 71).
The end result is an instance called paul pre-populated by the arguments 
that we passed to Person.

We can do that manually by not defining __init__()

class Person2:
    def setData(self, name, age):
        self.name = name
        self.age = age

paul = Person2()   # get a new empty Person2 object
paul.setData("Paul", 71)   # do the equivalent of __init__

print (paul.Name, paul.age)


> self.name <http://self.name/> = name                         # why
> assign name to self.name <http://self.name> variable?

Remember that name is the input parameter to the method.
Just like any other function the input parameters are just
temporary variables that get thrown away at the end of
the function. We want to store those values in our new
instance. So we assign them to a data attribute of the
new object(self) for storage so that we can access them
in the future. For example the salute() method accesses
the self.name attribute. It can only use that if it has
been stored previously.

We can add attributes to an object at any time in Python.
For instance, using our paul example above we can do this:

paul.instrument = "bass"

and later print paul.instrument.

The equivalent of doing that inside a method is to use self.
So we could have another method in Person like this:

class Person:
    def __init__(self, name, age):....
    def salute(self):....
    def joinBand(self, instrument):
        self.instrument = instrument

and we can call that method as before

paul = Person("Paul", 71)
paul.joinBand("bass")

So setting attributes can be done anywhere and from
any method it's not special to init. But because init
gets called automatically when we first create the
object it's convenient to be able to set the initial
values at the same time as we create the object.

Is that helping?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Tue Jan 21 11:18:49 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Tue, 21 Jan 2014 10:18:49 +0000
Subject: [Tutor] How to print certain elements
In-Reply-To: <BLU0-SMTP433730E278FD58756F42933E9A40@phx.gbl>
References: <BLU0-SMTP433730E278FD58756F42933E9A40@phx.gbl>
Message-ID: <lblhht$k6b$1@ger.gmane.org>

On 21/01/14 06:18, Adriansanchez wrote:
> Hello everyone,
> I am newbie to Python and programming in general. My question is, given a list:
> X=['washington','adams','jefferson','madison','monroe']
> And a string:
> Y='washington,adams,jefferson,madison,monroe'
>
> How would I print washington and monroe using   [:]?
> How would I print every element but those two names?

The [:] syntax is used for selecting a range of values
from a starting point to a finish.  Its not appropriate
for selecting arbitrary items out of the list.

If you know which items you want you can use a simple
index to access them (remember the first item is index 0)

So to print the first item and the fourth item:

print(X[0],X[3])

In your case it's the first and last so we can do
a similar thing:

print(X[0], X[4])

But for the last element we can alternatively use
a shortcut to save counting the indexes; that's use
an index of -1:

print(X[0],X[-1])

Printing every element except those two is harder.
The simplest approach is to use a loop to process
the list and test each value:

for name in X:
     if name not in (X[0], X[-1]):
        print name

For the special case of excluding the first and
last names you could use the [:] notation like
this:

print X[1:-1]

But that only works where you want *all* the
names in a sequence between two end points.

Finally there is a more advanced way of filtering
out items from a list called a list comprehension:

print ( [name for name in X if name not in (X[0],X[-1])] )

Which is pretty much our 'for' loop above, written in
a shorthand single line form.

hth

Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From denis.spir at gmail.com  Tue Jan 21 11:36:43 2014
From: denis.spir at gmail.com (spir)
Date: Tue, 21 Jan 2014 11:36:43 +0100
Subject: [Tutor] How to print certain elements
In-Reply-To: <BLU0-SMTP433730E278FD58756F42933E9A40@phx.gbl>
References: <BLU0-SMTP433730E278FD58756F42933E9A40@phx.gbl>
Message-ID: <52DE4DBB.3040100@gmail.com>

On 01/21/2014 07:18 AM, Adriansanchez wrote:
> Hello everyone,
> I am newbie to Python and programming in general. My question is, given a list:
> X=['washington','adams','jefferson','madison','monroe']
> And a string:
> Y='washington,adams,jefferson,madison,monroe'

Side note: you can generate X automatically from Y:

X = Y.split(",")
print(X)

split (as name says) splits a string into a list of substrings. The parameter is 
the separator separating the substrings. In standard (default value), meaning if 
you don't indicate a separator, python uses any whitespace (space, tab, newline) 
possibly repeted.

Denis

From steve at pearwood.info  Tue Jan 21 12:32:53 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Tue, 21 Jan 2014 22:32:53 +1100
Subject: [Tutor] Understanding Classes
In-Reply-To: <lbiqgt$f48$1@ger.gmane.org>
References: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
 <lbhocn$vg3$1@ger.gmane.org>
 <CABSj3_6dxn=CYNaazpTjpHyTZgu2yc8gmM4vjgP=ir-ZBqj7Jw@mail.gmail.com>
 <lbiqgt$f48$1@ger.gmane.org>
Message-ID: <20140121113253.GC3915@ando>

On Mon, Jan 20, 2014 at 09:33:29AM +0000, Alan Gauld wrote:

> >However, I understand that classes are
> >parallel to that of a blueprint,
> 
> Yes, they define what the objects will look like, what data and what 
> methods they contain. But to use those objects you have to instantiate 
> them and its there that the usage varies slightly from the built in types:
> 
> For built in string type objects you do this
> 
> mystring = 'a new string object'
> 
> But if String were a user defined class you'd need to do this:
> 
> mystring = String('a user defined string object')

Just to be clear here, the difference is a simple matter of syntax. 
Because strings are so common in programming, Python gives you special 
syntax for creating strings. When you have code like this:

'a new string object'

Python still has to create a string object, exactly the same as with a 
custom class. The only difference is that creating strings is handled 
automatically, by the Python interpreter, rather than by you having to 
create your own String class. (Of course you can create a string class 
if you so wish.)


-- 
Steven

From eryksun at gmail.com  Tue Jan 21 12:33:02 2014
From: eryksun at gmail.com (eryksun)
Date: Tue, 21 Jan 2014 06:33:02 -0500
Subject: [Tutor] How to print certain elements
In-Reply-To: <lblhht$k6b$1@ger.gmane.org>
References: <BLU0-SMTP433730E278FD58756F42933E9A40@phx.gbl>
 <lblhht$k6b$1@ger.gmane.org>
Message-ID: <CACL+1asRJM8mW2bd7bH0sZRF1DuvsumamTUuX5RW+JGVSQu46A@mail.gmail.com>

On Tue, Jan 21, 2014 at 5:18 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>
> for name in X:
>     if name not in (X[0], X[-1]):
>        print name
>
> For the special case of excluding the first and
> last names you could use the [:] notation like
> this:
>
> print X[1:-1]
>
> But that only works where you want *all* the
> names in a sequence between two end points.
>
> Finally there is a more advanced way of filtering
> out items from a list called a list comprehension:
>
> print ( [name for name in X if name not in (X[0],X[-1])] )

If you're using the `print` function, you can use the * operator to
unpack the items of the list. Add the option sep='\n' to print each
item on a separate line:

    items = [name for name in X if name not in (X[0],X[-1])]
    print(*items, sep='\n')

To get the `print` function in 2.x, add the following to the top of your module:

    from __future__ import print_function

From steve at pearwood.info  Tue Jan 21 13:18:15 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Tue, 21 Jan 2014 23:18:15 +1100
Subject: [Tutor] Understanding Classes
In-Reply-To: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
References: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
Message-ID: <20140121121814.GD3915@ando>

On Sun, Jan 19, 2014 at 04:59:58PM -0500, Christian Alexander wrote:
> Hello Tutorians,
> 
> Looked all over the net for class tutorials
> Unable to understand the "self" argument
> Attempting to visual classes

Let me explain classes by analogy. Classes are best as representing 
things, that is, nouns, whether abstract nouns like numbers, or concrete 
nouns like cars. So let's work through an example.

Suppose I have a class Car. You might think of the class as a factory 
which creates cars. We call that factory a class, and the individual 
cars built by the factory "instances". (This analogy doesn't go far 
enough: there is a lot more to the relationship between instances and 
their class, but for now we'll start with this slightly inaccurate 
picture and then improve it later on.)

So the first thing that we do is we need to decide what sort of car the 
factory will produce. I don't mean the brand name and model, I mean, 
what does it do? What parts does it need? Two doors or four? So let's 
make a basic car that does just two things: it starts the engine, and 
stops the engine:

class Car:
    def start_engine(self):
        if self.gear not in ('Park', 'Neutral'):
            raise RuntimeError('cannot start engine')
        self.engine.start()

    def stop_engine(self):
        self.engine.stop()


Not a very interesting car, but all things must start somewhere. Now, 
lets look at those methods, `start_engine` and `stop_engine`. They take 
a single argument, `self`. What does self represent? It represents the 
individual car you wish to operate. You might end up with fifty cars:

car1 = Car()  # create a new car instance
car2 = Car()
car3 = Car()
...

Every one of those cars shares access to the same `start_engine` method. 
So when you call the method:

car23.start_engine()

how does the method know to start car23's engine, instead of car42 or 
car18? It knows because Python takes the bit before the dot (`car23`), 
and automatically passes it to the method as the `self` argument.

Confused? Let's make a brief side-track, and talk about functions. 
Here's a function:

def greet(name, greeting):
    print greeting, name

If I call that function:

greet("Fred", "Greetings and salutations")
=> prints "Greetings and salutations Fred"

Python takes the first value, "Fred", and assigns it to the argument 
`name`, the second value "Greetings and salutations" and assigns it to 
the argument `greeting`. Then the function can access them as local 
variables inside the function.

The same applies to methods, with just one additional bit of magic: when 
you call a method like this:

     instance.method(a, b, c)  # say

Python turns it into a function call:

     method(instance, a, b, c)

[For advanced readers: to be precise, Python uses what is technically 
known as an *unbound method*, which it gets by looking inside the class 
of `instance`. To be even more precise, in Python 3, it no longer uses 
unbound methods but just regular functions. But the basic concept is 
the same.]

So, back to our car: we've got a car that has two methods, which 
controls the *behaviour* of the car, but they won't do anything except 
raise an exception, because the car doesn't have any *state*. It has no 
engine to turn on or off, and it has no memory of what gear it is in. So 
let's fix that.

Every individual car needs its own engine, and each car needs to 
remember it's own gear. The obvious time to add the engine is when we 
create the car. Python creates the car when you call the class name as 
if it were a function: 

my_car = Car()  # Python creates the car instance

Now of course, Python doesn't know what cars are supposed to include, so 
it just does the bare minimum, which basically is just to allocate a 
small amount of memory for the instance and a few other bits of 
behind-the-scenes book-keeping. The rest is up to you, and that's what 
the __init__ method is for. So we give the car an engine when we create 
the car, and set the gear at the same time:


class Car:
    def __init__(self):
        self.engine = Engine()
        self.gear = "Neutral"

    def start_engine(self):
        if self.gear not in ('Park', 'Neutral'):
            raise RuntimeError('cannot start engine')
        self.engine.start()

    def stop_engine(self):
        self.engine.stop()



Of course, somebody has to write the Engine class too, but I can't be 
expected to do everything. Let's just pretend it already exists. Now you 
have a class which defines cars. When you call:

my_car = Car()

Python automatically calls the __init__ method with the newly created 
car instance as `self`. The __init__ method then runs, giving the car an 
engine, and setting the gear to neutral. Now, you should be able to 
start and stop the car:

my_car.start()
my_car.stop()


and provided the engine class knows how to start and stop, so will the 
car. So, in conclusion:

- the point of the `__init__` method is that Python automatically calls 
  that method when you create an instance, so that you can initialise 
  the instance with whatever state it needs to work;

- the point of the `self` argument is so that the method knows which 
  instance it ought to operate on.


Obviously what I have described here only scratches the surface of what 
classes do. I haven't described inheritance, and my Car class is so 
lacking in functionality that it is a joke. But I hope that it helps you 
understand __init__ and self.



-- 
Steven

From keithwins at gmail.com  Tue Jan 21 15:27:56 2014
From: keithwins at gmail.com (Keith Winston)
Date: Tue, 21 Jan 2014 09:27:56 -0500
Subject: [Tutor] How to print certain elements
In-Reply-To: <CACL+1asRJM8mW2bd7bH0sZRF1DuvsumamTUuX5RW+JGVSQu46A@mail.gmail.com>
References: <BLU0-SMTP433730E278FD58756F42933E9A40@phx.gbl>
 <lblhht$k6b$1@ger.gmane.org>
 <CACL+1asRJM8mW2bd7bH0sZRF1DuvsumamTUuX5RW+JGVSQu46A@mail.gmail.com>
Message-ID: <CAO5ffbanSzdmE9AZvvHCRD0gOKpy15UfRMp-o2eEN3ZCnJduXA@mail.gmail.com>

If you are playing around at the Python prompt (the >>>), which you
really should be to get the hang of this stuff, you might notice that
the bracket indexing that you and everyone is talking about works both
on strings (Y) and on lists (X: in this case, a list of strings). They
may not behave the same way as you expect. Try to imagine what Y[13]
or X[3][3] would get you, and why.

-- 
Keith

From eryksun at gmail.com  Tue Jan 21 16:14:42 2014
From: eryksun at gmail.com (eryksun)
Date: Tue, 21 Jan 2014 10:14:42 -0500
Subject: [Tutor] Understanding Classes
In-Reply-To: <20140121121814.GD3915@ando>
References: <CABSj3_7oo=dJht5q9OQP24_QHLjCivcYVz_CL3ifoRP=K6uL5g@mail.gmail.com>
 <20140121121814.GD3915@ando>
Message-ID: <CACL+1atiM_X=1rzVdSS+CRSo=VpZdjmxCjkT9-KuTmy1z6FnjA@mail.gmail.com>

On Tue, Jan 21, 2014 at 7:18 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> The same applies to methods, with just one additional bit of magic: when
> you call a method like this:
>
>      instance.method(a, b, c)  # say
>
> Python turns it into a function call:
>
>      method(instance, a, b, c)
>
> [For advanced readers: to be precise, Python uses what is technically
> known as an *unbound method*, which it gets by looking inside the class
> of `instance`. To be even more precise, in Python 3, it no longer uses
> unbound methods but just regular functions. But the basic concept is
> the same.]

You're using 2.x but didn't subclass `object`. Old-style classes
behave differently in many cases, starting with the most basic
difference:

    >>> type(my_car)
    <type 'instance'>

If you're targeting both 2.x and 3.x, remember to subclass `object` explicitly.

A minor correction about methods: it's a "bound" method:

    >>> my_car.start_engine.__self__ is my_car
    True

The wrapped function is `__func__`:

    >>> type(my_car.start_engine.__func__)
    <type 'function'>
    >>> my_car.start_engine.__func__.__name__
    'start_engine'

From fomcl at yahoo.com  Tue Jan 21 20:44:55 2014
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Tue, 21 Jan 2014 11:44:55 -0800 (PST)
Subject: [Tutor] when is "pythondontwritebytecode" useful?
In-Reply-To: <CACL+1auxjUkuA=8Uq3jEo-bh=vrKAbDAJv625yHjEUTH7FWacw@mail.gmail.com>
References: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
 <CACL+1auxjUkuA=8Uq3jEo-bh=vrKAbDAJv625yHjEUTH7FWacw@mail.gmail.com>
Message-ID: <1390333495.50223.YahooMailNeo@web163801.mail.gq1.yahoo.com>



>On Mon, Jan 20, 2014 at 5:42 AM, Albert-Jan Roskam <fomcl at yahoo.com> wrote:
>>
>> When is setting a PYTHONDONTWRITEBYTECODE environment variable useful? Or
>> set sys.dont_write_bytecode to True? Or start Python with the -B option?
>> I know what it does
>> (http://docs.python.org/2/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE),
>> i.e. no pyc or pyo fiules are written, but WHY is that sometimes a good
>> thing? The only useful scenario I can think of is when you don't have write
>> rights to create pyc files but you want to use a package anyway.
>
>The bug tracker can provide insight into why a given feature exists,
>or why it's implemented a certain way:
>
>Issue 602345: option for not writing .py[co] files
>http://bugs.python.org/issue602345


Hi Oscar, Eryksun,

Thanks for your replies. Good general tip to check the big tracker. Somehow Duckduckgo or Google did not find that page. Glad to read that I was sort of right: "Currently python tries to write the .py[co] files even
in situations, where it will fail, like on read-only
mounted file systems."

>> However, I recently opened an EGG file with a zip utility (because I knew
>> egg uses zipimport so it's a zip-like format) and I noticed that there
>> were .pyc files.
>
>Eggs are a binary distribution format. They contain byte-compiled .pyc
>files and extension modules. There's even an option to exclude .py
>source files. The filename should indicate the Python version and
>platform.
>
>Loading extension modules directly from an egg depends on the
>pkg_resources module from setuptools. The modules are extracted to a
>local cache directory. On Windows the default cache directory is
>"%APPDATA%\Python-Eggs", else it uses "~/.python-eggs". You can
>customize this with the environment variable PYTHON_EGG_CACHE.

Hmmm, number of OS * number of Python versions = a lot of packages. Isn't a .zip file easiest? Or maybe msi or wininst*) on Windows and .deb on Linux (with alien that can easily be converted to e.g. rpm).

*) Last time I tried creating a wininst under Linux it created an .exe file of correct/plausible size, but with a huge traceback. Never bothered to try if it did work. Maybe it was this: http://bugs.python.org/issue8954. The bug tracker is a useful source of information indeed. ;-)

regards,
Albert-Jan

From mmadlavana at gmail.com  Tue Jan 21 11:24:56 2014
From: mmadlavana at gmail.com (Mkhanyisi Madlavana)
Date: Tue, 21 Jan 2014 12:24:56 +0200
Subject: [Tutor] How to print certain elements
Message-ID: <CAD5sEnc+p1+i99PSrjKR-1DVFYk0EfOKvY6=XN6Wa0Hxxhkvnw@mail.gmail.com>

How would I print washington and monroe using   [:]?
print X[::3]
How would I print every element but those two names?
print X[1::2]


On 21 January 2014 12:18, Alan Gauld <alan.gauld at btinternet.com> wrote:

> On 21/01/14 06:18, Adriansanchez wrote:
>
>> Hello everyone,
>> I am newbie to Python and programming in general. My question is, given a
>> list:
>> X=['washington','adams','jefferson','madison','monroe']
>> And a string:
>> Y='washington,adams,jefferson,madison,monroe'
>>
>> How would I print washington and monroe using   [:]?
>> How would I print every element but those two names?
>>
>
> The [:] syntax is used for selecting a range of values
> from a starting point to a finish.  Its not appropriate
> for selecting arbitrary items out of the list.
>
> If you know which items you want you can use a simple
> index to access them (remember the first item is index 0)
>
> So to print the first item and the fourth item:
>
> print(X[0],X[3])
>
> In your case it's the first and last so we can do
> a similar thing:
>
> print(X[0], X[4])
>
> But for the last element we can alternatively use
> a shortcut to save counting the indexes; that's use
> an index of -1:
>
> print(X[0],X[-1])
>
> Printing every element except those two is harder.
> The simplest approach is to use a loop to process
> the list and test each value:
>
> for name in X:
>     if name not in (X[0], X[-1]):
>        print name
>
> For the special case of excluding the first and
> last names you could use the [:] notation like
> this:
>
> print X[1:-1]
>
> But that only works where you want *all* the
> names in a sequence between two end points.
>
> Finally there is a more advanced way of filtering
> out items from a list called a list comprehension:
>
> print ( [name for name in X if name not in (X[0],X[-1])] )
>
> Which is pretty much our 'for' loop above, written in
> a shorthand single line form.
>
> hth
>
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140121/85d4db7d/attachment.html>

From breamoreboy at yahoo.co.uk  Tue Jan 21 22:49:47 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Tue, 21 Jan 2014 21:49:47 +0000
Subject: [Tutor] How to print certain elements
In-Reply-To: <CAD5sEnc+p1+i99PSrjKR-1DVFYk0EfOKvY6=XN6Wa0Hxxhkvnw@mail.gmail.com>
References: <CAD5sEnc+p1+i99PSrjKR-1DVFYk0EfOKvY6=XN6Wa0Hxxhkvnw@mail.gmail.com>
Message-ID: <lbmq1l$mj3$1@ger.gmane.org>

On 21/01/2014 10:24, Mkhanyisi Madlavana wrote:
> How would I print washington and monroe using   [:]?
> print X[::3]
> How would I print every element but those two names?
> print X[1::2]
>
>
> On 21 January 2014 12:18, Alan Gauld <alan.gauld at btinternet.com
> <mailto:alan.gauld at btinternet.com>> wrote:
>
>     On 21/01/14 06:18, Adriansanchez wrote:
>
>         Hello everyone,
>         I am newbie to Python and programming in general. My question
>         is, given a list:
>         X=['washington','adams','__jefferson','madison','monroe']
>         And a string:
>         Y='washington,adams,jefferson,__madison,monroe'
>
>         How would I print washington and monroe using   [:]?
>         How would I print every element but those two names?
>
>
>     The [:] syntax is used for selecting a range of values
>     from a starting point to a finish.  Its not appropriate
>     for selecting arbitrary items out of the list.
>
>     If you know which items you want you can use a simple
>     index to access them (remember the first item is index 0)
>
>     So to print the first item and the fourth item:
>
>     print(X[0],X[3])
>
>     In your case it's the first and last so we can do
>     a similar thing:
>
>     print(X[0], X[4])
>
>     But for the last element we can alternatively use
>     a shortcut to save counting the indexes; that's use
>     an index of -1:
>
>     print(X[0],X[-1])
>
>     Printing every element except those two is harder.
>     The simplest approach is to use a loop to process
>     the list and test each value:
>
>     for name in X:
>          if name not in (X[0], X[-1]):
>             print name
>
>     For the special case of excluding the first and
>     last names you could use the [:] notation like
>     this:
>
>     print X[1:-1]
>
>     But that only works where you want *all* the
>     names in a sequence between two end points.
>
>     Finally there is a more advanced way of filtering
>     out items from a list called a list comprehension:
>
>     print ( [name for name in X if name not in (X[0],X[-1])] )
>
>     Which is pretty much our 'for' loop above, written in
>     a shorthand single line form.
>
>     hth
>

If you must top post please get your facts right.

In [1]: X=['washington','adams','jefferson','madison','monroe']

In [2]: print(X[::3])
['washington', 'madison']

In [3]: print(X[1::2])
['adams', 'madison']

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

Mark Lawrence


From adamhurwitz at google.com  Wed Jan 22 05:24:54 2014
From: adamhurwitz at google.com (Adam Hurwitz)
Date: Tue, 21 Jan 2014 20:24:54 -0800
Subject: [Tutor] Stuck on Challenge in Google Python Class
Message-ID: <CAG2KLvdzFE+SyvrCx3VB=i1uzzsrzFYFFL2RcNHfh9Tq_Pwn0A@mail.gmail.com>

Hi,

This is a coding challenge in the Google Developers Python
Course<https://developers.google.com/edu/python/exercises/basic>.
I have been working on this challenge for hours without being able to solve.

A. match_ends
# Given a list of strings, return the count of the number of
# strings where the string length is 2 or more and the first
# and last chars of the string are the same.
# Note: python does not have a ++ operator, but += works.'

Try #1:

def match_ends(words):
  numberStrings = [ ]
  answer = ' '

  for string in words:
    if len(string) >=2 or string[0] == string[-1]:
      numberStrings.append(string)
    else:
      return ' '

  answer = len(numberStrings)
  print answer



def match_ends(words):

# Calls the above functions with interesting inputs.
def main():
  print 'match_ends'
  test(match_ends(['aba', 'xyz', 'aa', 'x', 'bbb']), 3)
  test(match_ends(['', 'x', 'xy', 'xyx', 'xx']), 2)
  test(match_ends(['aaa', 'be', 'abc', 'hello']), 1)


Tries 2 and on: I wanted to get just the part working to check to see if
the first and last character are the same. I tried setting up a for loop
within a for loop. The first loop cycles through each word in the list,
then the second for loop cycles through each letter to compare if the first
character is equal to the last or not. I cannot get it to compare the first
and last letter properly.

Help solving this would be very much appreciated!!

Thank you for the help,

Adam
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140121/63f79660/attachment.html>

From denis.spir at gmail.com  Wed Jan 22 10:38:54 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 22 Jan 2014 10:38:54 +0100
Subject: [Tutor] Stuck on Challenge in Google Python Class
In-Reply-To: <CAG2KLvdzFE+SyvrCx3VB=i1uzzsrzFYFFL2RcNHfh9Tq_Pwn0A@mail.gmail.com>
References: <CAG2KLvdzFE+SyvrCx3VB=i1uzzsrzFYFFL2RcNHfh9Tq_Pwn0A@mail.gmail.com>
Message-ID: <52DF91AE.4010100@gmail.com>

On 01/22/2014 05:24 AM, Adam Hurwitz wrote:
> Hi,
>
> This is a coding challenge in the Google Developers Python
> Course<https://developers.google.com/edu/python/exercises/basic>.
> I have been working on this challenge for hours without being able to solve.
>
> A. match_ends
> # Given a list of strings, return the count of the number of
> # strings where the string length is 2 or more and the first
> # and last chars of the string are the same.
> # Note: python does not have a ++ operator, but += works.'
>
> Try #1:
>
> def match_ends(words):
>    numberStrings = [ ]
>    answer = ' '
>
>    for string in words:
>      if len(string) >=2 or string[0] == string[-1]:
>        numberStrings.append(string)
>      else:
>        return ' '
>
>    answer = len(numberStrings)
>    print answer

1. What is asked for is just the number of strings matching a given criterion, 
right? So you don't need to collect them into a list, then get the list's count 
of items: you could just count them as you go (as you traverse them in the 'for' 
loop).

2. You criterion is wrong. Please read again the problem and compare to your 
translation into programming code:
	(len(string) >= 2) or (string[0] == string[-1])

[If you cannot find a right solution according to 1. & 2., we'll help you further.]

> def match_ends(words):
>
> # Calls the above functions with interesting inputs.
> def main():
>    print 'match_ends'
>    test(match_ends(['aba', 'xyz', 'aa', 'x', 'bbb']), 3)
>    test(match_ends(['', 'x', 'xy', 'xyx', 'xx']), 2)
>    test(match_ends(['aaa', 'be', 'abc', 'hello']), 1)
>
>
> Tries 2 and on: I wanted to get just the part working to check to see if
> the first and last character are the same. I tried setting up a for loop
> within a for loop. The first loop cycles through each word in the list,
> then the second for loop cycles through each letter to compare if the first
> character is equal to the last or not. I cannot get it to compare the first
> and last letter properly.

1. The first half of the criterion is necessary for the second half to make 
sense, isn't it? (think hard ;-)
2. There is no simple way to compare first & last chars by iterating through all 
chars (you need to memorise the first char, then wait until you reach the last 
one, then only compare), and it is big overkill. Why do you want to do that at 
all? (you'd have to do that if python lists were linked lists, but they are 
flexible-size *arrays*: you can access any item by index)

Finally, an interesting challenge: generalise this into a function that counts 
the number of items in a collection (list, set...) matching a given criterion:

	def n_matches (coll, crit):
	    # ....
	    return n

[This could be a python builtin func or method, if it were commonly needed.]

Denis

From davea at davea.name  Wed Jan 22 11:10:55 2014
From: davea at davea.name (Dave Angel)
Date: Wed, 22 Jan 2014 05:10:55 -0500 (EST)
Subject: [Tutor] Stuck on Challenge in Google Python Class
References: <CAG2KLvdzFE+SyvrCx3VB=i1uzzsrzFYFFL2RcNHfh9Tq_Pwn0A@mail.gmail.com>
Message-ID: <lbo5ai$vga$1@ger.gmane.org>

 Adam Hurwitz <adamhurwitz at google.com> Wrote in message:
>

Many times when a function doesn't work, and you can't figure out
 why, it pays to factor the function,  at least temporarily,  and
 test the different parts.  This might be your best bet in this
 case,  especially when I tell you that you're very close.
 

I therefore suggest you separate the list part from the testing
 part.  Write a function that just takes a string, and returns
 True or False,  and have the current one call it
in the loop. 
 Don't worry yet about efficiency.  (get it correct,  get it
 readable,  and then only if it's too slow or too big, get it
 efficient)

Did you leave this message as html? You'll do better to use plain
 text here.
> 

iiiiiiiiiiiiiiii
mmmmm

-- 
DaveA


From steve at pearwood.info  Wed Jan 22 12:07:47 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 22 Jan 2014 22:07:47 +1100
Subject: [Tutor] Stuck on Challenge in Google Python Class
In-Reply-To: <CAG2KLvdzFE+SyvrCx3VB=i1uzzsrzFYFFL2RcNHfh9Tq_Pwn0A@mail.gmail.com>
References: <CAG2KLvdzFE+SyvrCx3VB=i1uzzsrzFYFFL2RcNHfh9Tq_Pwn0A@mail.gmail.com>
Message-ID: <20140122110747.GE3915@ando>

On Tue, Jan 21, 2014 at 08:24:54PM -0800, Adam Hurwitz wrote:
> Hi,
> 
> This is a coding challenge in the Google Developers Python
> Course<https://developers.google.com/edu/python/exercises/basic>.
> I have been working on this challenge for hours without being able to solve.
> 
> A. match_ends
> # Given a list of strings, return the count of the number of
> # strings where the string length is 2 or more and the first
> # and last chars of the string are the same.

How would you solve it as a human being?

Start with the count of matching strings as zero.
Look at each string in turn, one at a time.
If that string has length greater than two, AND the ends match, increase 
the count by one.

Start with that, then turn it into Python code as below:


> def match_ends(words):
>   numberStrings = [ ]
>   answer = ' '
>   for string in words:
>     if len(string) >=2 or string[0] == string[-1]:
>       numberStrings.append(string)
>     else:
>       return ' '
>   answer = len(numberStrings)
>   print answer


No need to record each string itself. You only need to count them.

count = 0  # start with count of zero
count += 1  # add one

Also, take note that the condition described is that the length of the 
string is two or greater, AND that the ends match. You have that the 
length of the string is two or greater, OR that the ends match.



-- 
Steven

From alan.gauld at btinternet.com  Wed Jan 22 12:40:57 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 22 Jan 2014 11:40:57 +0000
Subject: [Tutor] Stuck on Challenge in Google Python Class
In-Reply-To: <CAG2KLvdzFE+SyvrCx3VB=i1uzzsrzFYFFL2RcNHfh9Tq_Pwn0A@mail.gmail.com>
References: <CAG2KLvdzFE+SyvrCx3VB=i1uzzsrzFYFFL2RcNHfh9Tq_Pwn0A@mail.gmail.com>
Message-ID: <lboans$1rf$1@ger.gmane.org>

On 22/01/14 04:24, Adam Hurwitz wrote:

> A. match_ends
> # Given a list of strings, return the count of the number of
> # strings where the string length is 2 or more and the first
> # and last chars of the string are the same.

Notice that you are asked to *return* a number not print it.
Also notice that the condition is an AND not an OR.

> def match_ends(words):
>    numberStrings = [ ]
>    answer = ' '
>
>    for string in words:
>      if len(string) >=2 or string[0] == string[-1]:
>        numberStrings.append(string)
>      else:
>        return ' '

Notice that this return will throw you out of the function so
you don't process any more strings. You might like to look
at 'continue' as an alternative.

>    answer = len(numberStrings)
>    print answer

And here you print the result not return it.
So the return value from your function as is will be None or ''

But you are quite close to the solution.

HTH

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From yanglei.fage at gmail.com  Wed Jan 22 14:49:55 2014
From: yanglei.fage at gmail.com (lei yang)
Date: Wed, 22 Jan 2014 21:49:55 +0800
Subject: [Tutor] how to send "ctrl+a+c" with python
Message-ID: <CAHsH0E9Zg9khgjxMUHROw2Nc7MTmpMFe9cDchkWRc1Zs+JUS=Q@mail.gmail.com>

Hi expert,

I want to use pexpect to send "ctrl+a+c"
how should I do?

self.vm_session.sendline("????????")

how to fill ???????
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140122/63149130/attachment.html>

From eryksun at gmail.com  Wed Jan 22 15:35:08 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 22 Jan 2014 09:35:08 -0500
Subject: [Tutor] how to send "ctrl+a+c" with python
In-Reply-To: <CAHsH0E9Zg9khgjxMUHROw2Nc7MTmpMFe9cDchkWRc1Zs+JUS=Q@mail.gmail.com>
References: <CAHsH0E9Zg9khgjxMUHROw2Nc7MTmpMFe9cDchkWRc1Zs+JUS=Q@mail.gmail.com>
Message-ID: <CACL+1avRwy0zQq=VMg_0sB=Csp_W7OgTDYA=bOBENGgfU_W4ug@mail.gmail.com>

On Wed, Jan 22, 2014 at 8:49 AM, lei yang <yanglei.fage at gmail.com> wrote:
>
> I want to use pexpect to send "ctrl+a+c"

What's ctrl+a+c? If this is for screen, then I think you mean ctrl+a c:

    sendcontrol('a')
    send('c')

From yanglei.fage at gmail.com  Wed Jan 22 17:21:00 2014
From: yanglei.fage at gmail.com (lei yang)
Date: Thu, 23 Jan 2014 00:21:00 +0800
Subject: [Tutor] how to send "ctrl+a+c" with python
In-Reply-To: <CACL+1avRwy0zQq=VMg_0sB=Csp_W7OgTDYA=bOBENGgfU_W4ug@mail.gmail.com>
References: <CAHsH0E9Zg9khgjxMUHROw2Nc7MTmpMFe9cDchkWRc1Zs+JUS=Q@mail.gmail.com>
 <CACL+1avRwy0zQq=VMg_0sB=Csp_W7OgTDYA=bOBENGgfU_W4ug@mail.gmail.com>
Message-ID: <CAHsH0E8R_5Q4Uvii064AtjMd=niVCXy2YkzDuq-fsxofPGjb2A@mail.gmail.com>

thanks, it works for me

Lei



On Wed, Jan 22, 2014 at 10:35 PM, eryksun <eryksun at gmail.com> wrote:

> On Wed, Jan 22, 2014 at 8:49 AM, lei yang <yanglei.fage at gmail.com> wrote:
> >
> > I want to use pexpect to send "ctrl+a+c"
>
> What's ctrl+a+c? If this is for screen, then I think you mean ctrl+a c:
>
>     sendcontrol('a')
>     send('c')
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140123/8e533541/attachment.html>

From keithwins at gmail.com  Wed Jan 22 19:11:30 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 22 Jan 2014 13:11:30 -0500
Subject: [Tutor] Stuck on Challenge in Google Python Class
In-Reply-To: <lboans$1rf$1@ger.gmane.org>
References: <CAG2KLvdzFE+SyvrCx3VB=i1uzzsrzFYFFL2RcNHfh9Tq_Pwn0A@mail.gmail.com>
 <lboans$1rf$1@ger.gmane.org>
Message-ID: <CAO5ffbYv4URcdpsq-hHmmjCo9GbXs6NGP4iqYXzNM5b_GnrcNw@mail.gmail.com>

On Wed, Jan 22, 2014 at 6:40 AM, Alan Gauld <alan.gauld at btinternet.com> wrote:
>>      else:
>>        return ' '
>
>
> Notice that this return will throw you out of the function so
> you don't process any more strings. You might like to look
> at 'continue' as an alternative.

You actually don't need to do anything with this "else", and it's at
the end of the loop. You can just fall through to the next iteration.
Of course, others have already addressed the real problems (which were
few: you're close)


-- 
Keith

From eryksun at gmail.com  Wed Jan 22 20:01:18 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 22 Jan 2014 14:01:18 -0500
Subject: [Tutor] when is "pythondontwritebytecode" useful?
In-Reply-To: <1390333495.50223.YahooMailNeo@web163801.mail.gq1.yahoo.com>
References: <1390214577.37433.YahooMailNeo@web163803.mail.gq1.yahoo.com>
 <CACL+1auxjUkuA=8Uq3jEo-bh=vrKAbDAJv625yHjEUTH7FWacw@mail.gmail.com>
 <1390333495.50223.YahooMailNeo@web163801.mail.gq1.yahoo.com>
Message-ID: <CACL+1auH2WxkfKTcCdH78KCVaRfqFRnknFcgETsCzktmSHWtSQ@mail.gmail.com>

On Tue, Jan 21, 2014 at 2:44 PM, Albert-Jan Roskam <fomcl at yahoo.com> wrote:
>
> Hmmm, number of OS * number of Python versions = a lot of packages. Isn't
> a .zip file easiest? Or maybe msi or wininst*) on Windows and .deb on
> Linux (with alien that can easily be converted to e.g. rpm).

The egg format is old and tired. bdist_wheel is new and improved:

http://www.python.org/dev/peps/pep-0427/#comparison-to-egg

wininst lets the user uninstall through the control panel, and
easy_install can use it in a virtual environment. But as a
distribution format it requires separate 32-bit and 64-bit installers
even for pure-Python libraries. Also, pip works with wheel and not
wininst.

On Linux I wouldn't bother making a deb/rpm package -- not unless
you're the package maintainer for the distro. Most people will either
use a stable package from the repo or install a development package in
a virtual environment.

> Last time I tried creating a wininst under Linux it created an .exe
> file of correct/plausible size, but with a huge traceback. Never
> bothered to try if it did work. Maybe it was this:
> http://bugs.python.org/issue8954.

That issue shows a warning, not a traceback. The exe should be OK, but
rename it to use the correct platform name, either win32 or win-amd64
depending on which wininst exe was used.

From keithwins at gmail.com  Thu Jan 23 05:57:51 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 22 Jan 2014 23:57:51 -0500
Subject: [Tutor] iter class
Message-ID: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>

I'm working my way through some of the examples in

http://ivory.idyll.org/articles/advanced-swc/#list-comprehensions

And tried this one:

>>> class MyTrickyIter:
...   def __init__(self, thelist):
...      self.thelist = thelist
...      self.index = -1
...
...   def __iter__(self):
...      return self
...
...   def next(self):
...      self.index += 1
...      if self.index < len(self.thelist):
...         return self.thelist[self.index]
...      raise StopIteration

FYI, this is supposed to be an example of how NOT to do an iterator,
because of the way it handles thelist (which is supposed to be an
iteratable construct, like a list, if I'm not confused).

Anyway, my efforts to recreate the following example:

>>> mi = MyTrickyIter(['a', 'b'])
>>> for i in mi:
...   for j in mi:
...      print i, j

which should result in

a b

instead results in

Traceback (most recent call last):
  File "<pyshell#57>", line 1, in <module>
    for i in mi:
TypeError: iter() returned non-iterator of type 'MyTrickyIter'

I'm sort of wondering if there's a Py2 vs. Py3 issue here, but I don't see it.

-- 
Keith

From jeanpierreda at gmail.com  Thu Jan 23 06:21:05 2014
From: jeanpierreda at gmail.com (Devin Jeanpierre)
Date: Wed, 22 Jan 2014 21:21:05 -0800
Subject: [Tutor] iter class
In-Reply-To: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
Message-ID: <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>

On Wed, Jan 22, 2014 at 8:57 PM, Keith Winston <keithwins at gmail.com> wrote:
> I'm working my way through some of the examples in
>
> http://ivory.idyll.org/articles/advanced-swc/#list-comprehensions
>
> And tried this one:
>
>>>> class MyTrickyIter:
> ...   def __init__(self, thelist):
> ...      self.thelist = thelist
> ...      self.index = -1
> ...
> ...   def __iter__(self):
> ...      return self
> ...
> ...   def next(self):
> ...      self.index += 1
> ...      if self.index < len(self.thelist):
> ...         return self.thelist[self.index]
> ...      raise StopIteration
>
> FYI, this is supposed to be an example of how NOT to do an iterator,
> because of the way it handles thelist (which is supposed to be an
> iteratable construct, like a list, if I'm not confused).

thelist is more like a sequence, meaning you can use myseq[n] for every value of
n between and including 0 and len(myseq) -1. (Although, sequences
usually have other things, too.) An iterable is anything you can loop
over with a for loop.

This is a perfectly reasonable iterator, but iterators are always
tricky when used as an iterable -- you can't do a nested loop over a
single iterator, because the iterator used for both loops will be the
same iterator, and keep the same state.

> Anyway, my efforts to recreate the following example:
>
>>>> mi = MyTrickyIter(['a', 'b'])
>>>> for i in mi:
> ...   for j in mi:
> ...      print i, j
>
> which should result in
>
> a b
>
> instead results in
>
> Traceback (most recent call last):
>   File "<pyshell#57>", line 1, in <module>
>     for i in mi:
> TypeError: iter() returned non-iterator of type 'MyTrickyIter'
>
> I'm sort of wondering if there's a Py2 vs. Py3 issue here, but I don't see it.

in Python 3, it should be __next__, not next.

I'd suggest staying away from any old blog posts and articles, unless
you'd care to learn Python 2.x instead of 3.x. ;)

-- Devin

From keithwins at gmail.com  Thu Jan 23 06:53:46 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 00:53:46 -0500
Subject: [Tutor] iter class
In-Reply-To: <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
Message-ID: <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>

On Thu, Jan 23, 2014 at 12:21 AM, Devin Jeanpierre
<jeanpierreda at gmail.com> wrote:
> in Python 3, it should be __next__, not next.

Ah! That's it! Thanks!!!

> I'd suggest staying away from any old blog posts and articles, unless
> you'd care to learn Python 2.x instead of 3.x. ;)

Yeah, but this is a REALLY GOOD resource. But your point is
well-taken: on the simple stuff, i.e. print statements, I can see the
difference quickly. I suppose I should practice running my questions
on old code through 2to3 before I pester the Tutor list, since that's
probably also a good way to learn the differences.

Thanks for your help.
-- 
Keith

From __peter__ at web.de  Thu Jan 23 09:09:26 2014
From: __peter__ at web.de (Peter Otten)
Date: Thu, 23 Jan 2014 09:09:26 +0100
Subject: [Tutor] iter class
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
Message-ID: <lbqilu$5ot$1@ger.gmane.org>

Keith Winston wrote:

> On Thu, Jan 23, 2014 at 12:21 AM, Devin Jeanpierre
> <jeanpierreda at gmail.com> wrote:
>> in Python 3, it should be __next__, not next.
> 
> Ah! That's it! Thanks!!!
> 
>> I'd suggest staying away from any old blog posts and articles, unless
>> you'd care to learn Python 2.x instead of 3.x. ;)
> 
> Yeah, but this is a REALLY GOOD resource. But your point is
> well-taken: on the simple stuff, i.e. print statements, I can see the
> difference quickly. I suppose I should practice running my questions
> on old code through 2to3 before I pester the Tutor list, since that's
> probably also a good way to learn the differences.

Yes, that would have worked here. 

But why not install Python 2.7 on your machine, too? That would allow you 
run the examples as is.


From mackenzi.jackson at gmail.com  Thu Jan 23 01:27:33 2014
From: mackenzi.jackson at gmail.com (Mackenzi Jackson)
Date: Wed, 22 Jan 2014 19:27:33 -0500
Subject: [Tutor] downloading Python
Message-ID: <CAOCz5_tsVRMrT6mdDct39nTCWN0=38uFL38VN_djrva0pg2WwA@mail.gmail.com>

Hi there, I'm new to computers in general but I'd like to start programming
asap. I'm having trouble getting Python to run on my computer. Is this the
right place to seek help? If so, my mac is OS x 10.6.8 and I was trying to
run Mac Python 2.3.3 (I think). I've been trying for a few hours now and am
getting very frustrated. Got any tips?

Thanks for your time,
Mackenzi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140122/a4c82a94/attachment.html>

From breamoreboy at yahoo.co.uk  Thu Jan 23 10:47:05 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Thu, 23 Jan 2014 09:47:05 +0000
Subject: [Tutor] downloading Python
In-Reply-To: <CAOCz5_tsVRMrT6mdDct39nTCWN0=38uFL38VN_djrva0pg2WwA@mail.gmail.com>
References: <CAOCz5_tsVRMrT6mdDct39nTCWN0=38uFL38VN_djrva0pg2WwA@mail.gmail.com>
Message-ID: <lbqoek$7q2$1@ger.gmane.org>

On 23/01/2014 00:27, Mackenzi Jackson wrote:
> Hi there, I'm new to computers in general but I'd like to start
> programming asap. I'm having trouble getting Python to run on my
> computer. Is this the right place to seek help? If so, my mac is OS x
> 10.6.8 and I was trying to run Mac Python 2.3.3 (I think). I've been
> trying for a few hours now and am getting very frustrated. Got any tips?
>
> Thanks for your time,
> Mackenzi
>

The most important tip is not to waste your money on expensive, poor 
quality Apple products.

Having got that off of my chest I can't really help as both my main and 
spare crystal balls are currently being mended.  So if you'd be kind 
enough to tell us exactly what you've tried and exactly what went wrong 
then I'm certain that we'll be able to help.

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

Mark Lawrence


From dyoo at hashcollision.org  Thu Jan 23 11:07:16 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Thu, 23 Jan 2014 02:07:16 -0800
Subject: [Tutor] downloading Python
In-Reply-To: <CAOCz5_tsVRMrT6mdDct39nTCWN0=38uFL38VN_djrva0pg2WwA@mail.gmail.com>
References: <CAOCz5_tsVRMrT6mdDct39nTCWN0=38uFL38VN_djrva0pg2WwA@mail.gmail.com>
Message-ID: <CAGZAPF7CJUc_J7dSxW19YzhA1f26O03NmhLPSoUP03WBXGiTLA@mail.gmail.com>

Hi Mackenzi,

My understanding is that all Mac OS X computers have Python installed by
default.  You mentioned that you were starting to learn computers.  Do you
have some familiarity with Terminal?  If so, try 'python' at your terminal.

If not, you probably want a GUI environment to make things more pleasant.
It's a bit late tonight, so I can't check right now; I can check in
tomorrow when my brain is on, if no one else has piped in.

Ignore Mark's poke about Mac OS machines.  He gets grumpy---as do I at
times.  But he has a point in recommending being detailed when describing
problems or errors.  Try including more details, and that will give us more
to work with.

Good luck!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140123/03590561/attachment.html>

From alan.gauld at btinternet.com  Thu Jan 23 11:07:50 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 23 Jan 2014 10:07:50 +0000
Subject: [Tutor] downloading Python
In-Reply-To: <CAOCz5_tsVRMrT6mdDct39nTCWN0=38uFL38VN_djrva0pg2WwA@mail.gmail.com>
References: <CAOCz5_tsVRMrT6mdDct39nTCWN0=38uFL38VN_djrva0pg2WwA@mail.gmail.com>
Message-ID: <lbqpla$mfc$1@ger.gmane.org>

On 23/01/14 00:27, Mackenzi Jackson wrote:

> programming asap. I'm having trouble getting Python to run on my
> computer. Is this the right place to seek help? If so, my mac is OS x
> 10.6.8 and I was trying to run Mac Python 2.3.3 (I think). I've been
> trying for a few hours now and am getting very frustrated. Got any tips?

Is the version important for some reason?

If not, your Mac has Python installed and you just
need to open the Terminal app and type 'python' at
the prompt. It will probably be at least Python 2.6
on your OS.

The version installed by default (and please don't
uninstall it!) does not, I think,  support Tkinter
GUI apps so if you want to start building those you
will need to download a dmg file and install it.

But to get started the default one should be fine.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From denis.spir at gmail.com  Thu Jan 23 11:56:10 2014
From: denis.spir at gmail.com (spir)
Date: Thu, 23 Jan 2014 11:56:10 +0100
Subject: [Tutor] iter class
In-Reply-To: <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
Message-ID: <52E0F54A.2070709@gmail.com>

On 01/23/2014 06:53 AM, Keith Winston wrote:
> I suppose I should practice running my questions
> on old code through 2to3 before I pester the Tutor list, since that's
> probably also a good way to learn the differences.

Yes, but that way others learn as well :-) And many people prefere learning via 
human interaction then dealing with arid texts (which, also, are unable to adapt 
to you, are they? maybe the day we have bio-animate AI text...).

Denis

From bouncingcats at gmail.com  Thu Jan 23 13:03:18 2014
From: bouncingcats at gmail.com (David)
Date: Thu, 23 Jan 2014 23:03:18 +1100
Subject: [Tutor] downloading Python
In-Reply-To: <CAOCz5_tsVRMrT6mdDct39nTCWN0=38uFL38VN_djrva0pg2WwA@mail.gmail.com>
References: <CAOCz5_tsVRMrT6mdDct39nTCWN0=38uFL38VN_djrva0pg2WwA@mail.gmail.com>
Message-ID: <CAMPXz=qw85E1nW+VaO1Rj9TWrHrgCwWBiUpSwHQg1zKBV8_u6w@mail.gmail.com>

On 23 January 2014 11:27, Mackenzi Jackson <mackenzi.jackson at gmail.com> wrote:
> Hi there, I'm new to computers in general but I'd like to start programming
> asap. I'm having trouble getting Python to run on my computer. Is this the
> right place to seek help? If so, my mac is OS x 10.6.8 and I was trying to
> run Mac Python 2.3.3 (I think). I've been trying for a few hours now and am
> getting very frustrated. Got any tips?

Tip #1: If you don't tell us exactly what you tried, exactly what happened when
you tried it, and why that was unsatisfactory for you -- all in detail! -- then
your question is so vague that you will only get vague answers, or perhaps
no answers at all because volunteers like us get satisfaction from
actually solving problems, not writing vague emails like this.

Personally I'm not a Mac user. I prefer computers that don't try to restrict
what their owners can do. But I imagine there will be some Mac users here too.

Tip #2: Another vague reply I can offer you is that the official
documentation is here:
http://www.python.org/download/mac/

Tip #3: And if I were in your situation ("new to computers"), I strongly
recommend asking first here (or on the main python mailing list)
before installing anything mentioned there, to check if it would
actually assist whatever situation you are experiencing. Because
newbies often install the wrong things for the wrong reasons, and
create a terrible mess that's hard to unscramble.

So ask first! But ask with details: "I am experiencing X problem,
would installing Y be advisable?"

Good luck! Python is a great choice of first language.

From eryksun at gmail.com  Thu Jan 23 13:05:19 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 23 Jan 2014 07:05:19 -0500
Subject: [Tutor] iter class
In-Reply-To: <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
Message-ID: <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>

On Thu, Jan 23, 2014 at 12:53 AM, Keith Winston <keithwins at gmail.com> wrote:
>> in Python 3, it should be __next__, not next.
>
> Ah! That's it! Thanks!!!

Generally you'll make `__iter__` a generator, so you don't have to
worry about implementing `__next__`. Also, the built-in function
`next` was added in 2.6, so you don't have to worry about the method
name difference between 2.x and 3.x, either.

From keithwins at gmail.com  Thu Jan 23 16:45:08 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 10:45:08 -0500
Subject: [Tutor] iter class
In-Reply-To: <52E0F54A.2070709@gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
 <52E0F54A.2070709@gmail.com>
Message-ID: <CAO5ffbbq9bEusqueDUqwGMmex3WfR82CH8D754pN0pLR=RJ6fw@mail.gmail.com>

On Thu, Jan 23, 2014 at 5:56 AM, spir <denis.spir at gmail.com> wrote:
> Yes, but that way others learn as well :-) And many people prefere learning
> via human interaction then dealing with arid texts

Well, you caught me. I do run out of steam just plowing through
lessons & such: it really helps to have actual humans to interact with
(well, as far as I know you're all actual humans... I can think of
Tutor as a kind of Turing test :)  I know that some people may prefer
fewer rather than more posts on the list, but I subscribe to your
"others learn as well" approach: I read all the posts and answers
here, including those that are above my understanding, and often get
little tidbits of insight. And I really can't rave too much about how
helpful people are here. That said, I have been trying to be a little
less dominating of the list!

-- 
Keith

From keithwins at gmail.com  Thu Jan 23 16:47:18 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 10:47:18 -0500
Subject: [Tutor] iter class
In-Reply-To: <lbqilu$5ot$1@ger.gmane.org>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
 <lbqilu$5ot$1@ger.gmane.org>
Message-ID: <CAO5ffbZoj+gLGhV3FjJFk9C4pArTNbQQp5Abpeq63_XosJcACA@mail.gmail.com>

On Thu, Jan 23, 2014 at 3:09 AM, Peter Otten <__peter__ at web.de> wrote:
> But why not install Python 2.7 on your machine, too? That would allow you
> run the examples as is.

Y'know, it's funny, but I have 2.7 installed. But since I was almost
certain it was a 2to3 kind of problem, I wanted to figure it out. Ok,
maybe... get you all to figure it out :)  That said, I did spend a
while poking around trying to figure it out.

-- 
Keith

From keithwins at gmail.com  Thu Jan 23 16:50:26 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 10:50:26 -0500
Subject: [Tutor] iter class
In-Reply-To: <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
 <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>
Message-ID: <CAO5ffbZhUk6_=-Z7e+2jSart2EK09Oe3FwvTgFHgOw-VOaSg8w@mail.gmail.com>

On Thu, Jan 23, 2014 at 7:05 AM, eryksun <eryksun at gmail.com> wrote:
> Generally you'll make `__iter__` a generator, so you don't have to
> worry about implementing `__next__`. Also, the built-in function
> `next` was added in 2.6, so you don't have to worry about the method
> name difference between 2.x and 3.x, either.

Yes, the exercise was about implementing an iter incorrectly, to see
the difference. But I don't really understand your second point: when
I changed the method name, it worked...?


-- 
Keith

From eryksun at gmail.com  Thu Jan 23 17:07:37 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 23 Jan 2014 11:07:37 -0500
Subject: [Tutor] iter class
In-Reply-To: <CAO5ffbZhUk6_=-Z7e+2jSart2EK09Oe3FwvTgFHgOw-VOaSg8w@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
 <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>
 <CAO5ffbZhUk6_=-Z7e+2jSart2EK09Oe3FwvTgFHgOw-VOaSg8w@mail.gmail.com>
Message-ID: <CACL+1aszAT12XMBcihR35V9PxHdVydFCXUziSFx8oUvFO6cARA@mail.gmail.com>

On Thu, Jan 23, 2014 at 10:50 AM, Keith Winston <keithwins at gmail.com> wrote:
> On Thu, Jan 23, 2014 at 7:05 AM, eryksun <eryksun at gmail.com> wrote:
>> Generally you'll make `__iter__` a generator, so you don't have to
>> worry about implementing `__next__`. Also, the built-in function
>> `next` was added in 2.6, so you don't have to worry about the method
>> name difference between 2.x and 3.x, either.
>
> Yes, the exercise was about implementing an iter incorrectly, to see
> the difference. But I don't really understand your second point: when
> I changed the method name, it worked...?

The page you sited discusses iterating the "old-fashioned way" in a
loop that calls `some_iter.next()`. Nowadays it's `next(some_iter)`,
which works in 2.6+ and 3.x. So if `__iter__` is a generator, you
don't implement '__next__` and generally won't have to call it
explicitly -- unless for some reason you need to pass the bound method
as a callable.

From jeanpierreda at gmail.com  Thu Jan 23 19:36:43 2014
From: jeanpierreda at gmail.com (Devin Jeanpierre)
Date: Thu, 23 Jan 2014 10:36:43 -0800
Subject: [Tutor] iter class
In-Reply-To: <CAO5ffbZhUk6_=-Z7e+2jSart2EK09Oe3FwvTgFHgOw-VOaSg8w@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
 <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>
 <CAO5ffbZhUk6_=-Z7e+2jSart2EK09Oe3FwvTgFHgOw-VOaSg8w@mail.gmail.com>
Message-ID: <CABicbJ+UrU6xm3Lb56Jn3mbb+vcqYdeuxea5heWeyzOmVVFbGA@mail.gmail.com>

On Thu, Jan 23, 2014 at 7:50 AM, Keith Winston <keithwins at gmail.com> wrote:
> Yes, the exercise was about implementing an iter incorrectly, to see
> the difference. But I don't really understand your second point: when
> I changed the method name, it worked...?

Again, nothing was incorrect about the example. Every iterator has
this "problem".

I question how good your resource is, if this is the impression it's
leaving you.

-- Devin

From keithwins at gmail.com  Thu Jan 23 20:18:33 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 14:18:33 -0500
Subject: [Tutor] iter class
In-Reply-To: <CABicbJ+UrU6xm3Lb56Jn3mbb+vcqYdeuxea5heWeyzOmVVFbGA@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
 <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>
 <CAO5ffbZhUk6_=-Z7e+2jSart2EK09Oe3FwvTgFHgOw-VOaSg8w@mail.gmail.com>
 <CABicbJ+UrU6xm3Lb56Jn3mbb+vcqYdeuxea5heWeyzOmVVFbGA@mail.gmail.com>
Message-ID: <CAO5ffbYYxacWLn_58YrJ3867keydZOw_qU-TmR79Cuqwp6RS4Q@mail.gmail.com>

On Thu, Jan 23, 2014 at 1:36 PM, Devin Jeanpierre
<jeanpierreda at gmail.com> wrote:

> Again, nothing was incorrect about the example. Every iterator has
> this "problem".

Hmmm. Well, here's what he actually said about that example, since I
don't think I've explained correctly:

*****
With iterators, one thing to watch out for is the return of self from
the __iter__ function. You can all too easily write an iterator that
isn't as re-usable as you think it is. For example, suppose you had
the following class:

{my example here}

This works just like you'd expect as long as you create a new object each time:

>>> for i in MyTrickyIter(['a', 'b']):
...   for j in MyTrickyIter(['a', 'b']):
...      print i, j
a a
a b
b a
b b

but it will break if you create the object just once:

{my example here, yielding only a single a b from the above loop}
******

The difference essentially comes down to the line

...      self.thelist = thelist  # in the "broken" example, vs.

...      self.thelist = iter(thelist)  # the "better" way to do it,
restarts the iterator each time a new loop uses it

I'm pretty sure I'm not really saying this right, it takes time
(apparently, for me) to understand how to speak clearly of these
things. The more important element, of course, is when my fuzzy
speaking speaks to fuzzy thinking, of which I am grateful for
correction.

-- 
Keith

From keithwins at gmail.com  Thu Jan 23 20:24:20 2014
From: keithwins at gmail.com (Keith Winston)
Date: Thu, 23 Jan 2014 14:24:20 -0500
Subject: [Tutor] iter class
In-Reply-To: <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
 <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>
Message-ID: <CAO5ffbaHNTYSpE48ZbRPmfc0AjS2_1FHaF2HEAj2WyDK1VEwDg@mail.gmail.com>

On Thu, Jan 23, 2014 at 7:05 AM, eryksun <eryksun at gmail.com> wrote:
> Generally you'll make `__iter__` a generator, so you don't have to
> worry about implementing `__next__`. Also, the built-in function
> `next` was added in 2.6, so you don't have to worry about the method
> name difference between 2.x and 3.x, either.

I'm now realizing I don't understand this comment at all. First, there
IS a __iter__ method in the example: does the presence of such make it
a generator already, or is it a usage thing, or something else? I
don't yet completely understand the difference/point... or maybe you
mean inherit the generator class?

Second: you state that I don't have to worry about the name
difference, but when I changed the method name from next to __next__
it worked in 3.3. So what's your point here?

I'm just realizing I'm missing your pearls of wisdom, not intending on
being combative or something.
-- 
Keith

From eryksun at gmail.com  Thu Jan 23 20:48:24 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 23 Jan 2014 14:48:24 -0500
Subject: [Tutor] iter class
In-Reply-To: <CAO5ffbaHNTYSpE48ZbRPmfc0AjS2_1FHaF2HEAj2WyDK1VEwDg@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
 <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>
 <CAO5ffbaHNTYSpE48ZbRPmfc0AjS2_1FHaF2HEAj2WyDK1VEwDg@mail.gmail.com>
Message-ID: <CACL+1atBUU0k1aYMrSEO0MfRTKKUjfGjEmGA11+8J25tdvMvwA@mail.gmail.com>

On Thu, Jan 23, 2014 at 2:24 PM, Keith Winston <keithwins at gmail.com> wrote:
> On Thu, Jan 23, 2014 at 7:05 AM, eryksun <eryksun at gmail.com> wrote:
>> Generally you'll make `__iter__` a generator, so you don't have to
>> worry about implementing `__next__`. Also, the built-in function
>> `next` was added in 2.6, so you don't have to worry about the method
>> name difference between 2.x and 3.x, either.
>
> I'm now realizing I don't understand this comment at all. First, there
> IS a __iter__ method in the example: does the presence of such make it
> a generator already, or is it a usage thing, or something else? I
> don't yet completely understand the difference/point... or maybe you
> mean inherit the generator class?

Sorry, sloppy language. You'll make `__iter__` a generator *function*
that returns a generator, which is an iterator (i.e. has a `__next__`
method). This works in 2.6+ and 3.x without needing any kludges or
2to3. For example:

    class MyIter:
        def __init__(self, thelist):
            self.thelist = thelist
        def __iter__(self):
            for item in self.thelist:
                yield item

    my_iter = MyIter(['a', 'b'])
    it = iter(my_iter)

    >>> type(it)
    <class 'generator'>

    >>> next(it)
    'a'
    >>> next(it)
    'b'

    >>> list(it)  # exhausted
    []

> Second: you state that I don't have to worry about the name
> difference, but when I changed the method name from next to __next__
> it worked in 3.3. So what's your point here?

The 2nd statement in my original comment was contingent on the first,
which I apparently failed to clarify in the followup.

From steve at pearwood.info  Fri Jan 24 01:16:54 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Jan 2014 11:16:54 +1100
Subject: [Tutor] iter class
In-Reply-To: <CAO5ffbYYxacWLn_58YrJ3867keydZOw_qU-TmR79Cuqwp6RS4Q@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
 <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>
 <CAO5ffbZhUk6_=-Z7e+2jSart2EK09Oe3FwvTgFHgOw-VOaSg8w@mail.gmail.com>
 <CABicbJ+UrU6xm3Lb56Jn3mbb+vcqYdeuxea5heWeyzOmVVFbGA@mail.gmail.com>
 <CAO5ffbYYxacWLn_58YrJ3867keydZOw_qU-TmR79Cuqwp6RS4Q@mail.gmail.com>
Message-ID: <20140124001654.GN3915@ando>

On Thu, Jan 23, 2014 at 02:18:33PM -0500, Keith Winston wrote:
> On Thu, Jan 23, 2014 at 1:36 PM, Devin Jeanpierre
> <jeanpierreda at gmail.com> wrote:
> 
> > Again, nothing was incorrect about the example. Every iterator has
> > this "problem".
> 
> Hmmm. Well, here's what he actually said about that example, since I
> don't think I've explained correctly:

Who is "he"?


> *****
> With iterators, one thing to watch out for is the return of self from
> the __iter__ function. You can all too easily write an iterator that
> isn't as re-usable as you think it is. For example, suppose you had
> the following class:

To be pedantic, an iterator isn't an iterator unless __iter__ returns 
self. Let's look at something which is *iterable* but not an iterator: a 
lsit. You can iterate over a list, as you know, but iter() (which calls 
__iter__ under the hood) does not return the list itself:

py> L = [1, 2, 4, 8]
py> iter(L) is L
False
py> iter(L)
<list_iterator object at 0xb7b77f6c>

Notice that list.__iter__ returns a special list_iterator object. That 
is an actual iterator:

py> it = iter(L)
py> iter(it) is it
True

One definining characteristic of an iterator is that you can call iter() 
on it as many times as you like, and you'll always get the same object.


[...]
> {my example here}
> 
> This works just like you'd expect as long as you create a new object each time:
> 
> >>> for i in MyTrickyIter(['a', 'b']):
> ...   for j in MyTrickyIter(['a', 'b']):
> ...      print i, j
> a a
> a b
> b a
> b b
> 
> but it will break if you create the object just once:
> 
> {my example here, yielding only a single a b from the above loop}

I think your example was something like this:

it = MyTrickyIter(['a', 'b'])
for i in it:
    for j in it:
        print i, j


which just prints "a b" and then is done.

This should not be considered a bug in iterators! It's a feature, 
working as designed. If you don't want that behaviour, then you 
shouldn't use the same iterator in both the outer and inner loops.

For example, if you want to grab items of a sequence in lots of three, 
you can do something like this:

py> L = iter(range(12))
py> for a, b, c in zip(L, L, L):
...     print(a, b, c)
...
0 1 2
3 4 5
6 7 8
9 10 11


Each time you go around the loop, zip() grabs one item from each 
argument. Since the arguments all correspond to the same iterator, that 
is equivalent to grabbing three items each time around the loop.


> ******
> 
> The difference essentially comes down to the line
> 
> ...      self.thelist = thelist  # in the "broken" example, vs.

But it's not broken at all. Remember that mysterious "list_iterator" 
object we saw earlier? That is probably implemented something quite like 
this so-called "broken" (not really) example.


> ...      self.thelist = iter(thelist)  # the "better" way to do it,
> restarts the iterator each time a new loop uses it

But then it isn't an iterator. It's something else. Perhaps something 
useful, but not an iterator. 


-- 
Steven

From steve at pearwood.info  Fri Jan 24 01:43:48 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Jan 2014 11:43:48 +1100
Subject: [Tutor] iter class
In-Reply-To: <CAO5ffbaHNTYSpE48ZbRPmfc0AjS2_1FHaF2HEAj2WyDK1VEwDg@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
 <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>
 <CAO5ffbaHNTYSpE48ZbRPmfc0AjS2_1FHaF2HEAj2WyDK1VEwDg@mail.gmail.com>
Message-ID: <20140124004348.GO3915@ando>

On Thu, Jan 23, 2014 at 02:24:20PM -0500, Keith Winston wrote:
> On Thu, Jan 23, 2014 at 7:05 AM, eryksun <eryksun at gmail.com> wrote:
> > Generally you'll make `__iter__` a generator, so you don't have to
> > worry about implementing `__next__`. Also, the built-in function
> > `next` was added in 2.6, so you don't have to worry about the method
> > name difference between 2.x and 3.x, either.
> 
> I'm now realizing I don't understand this comment at all. First, there
> IS a __iter__ method in the example: does the presence of such make it
> a generator already, or is it a usage thing, or something else? I
> don't yet completely understand the difference/point... or maybe you
> mean inherit the generator class?

Generators are a kind of function, which are special. You can't inherit 
from them:

py> def generator():
...     yield 1
...
py> class MyGenerator(type(generator)):
...     pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: type 'function' is not an acceptable base type


although I expect that should probably be considered an implementation 
detail of CPython rather than a language features. (Some other Pythons 
may allow you to inherit from function, if they wanted to.)

Eryksun means that when you write an iterable class, you might be 
tempted to manage the next method yourself, but nine times out of ten 
you don't need to, you can delegate the annoying part of the coding to 
Python. That is, instead of creating an *actual* iterator:

# Pseudocode
class MyIterator:
    def __iter__(self):
        return self
    def __next__(self):
        # I have to manage this myself...
        if there still are items to process:
            return the next item
        else:
            raise StopIteration


you can *return* an iterator. This makes your class a mock or 
pseudo-iterator, I suppose, although for the most part only pedants 
normally worry about the difference and we normally call it an iterator 
and hope nobody gets confused. But for now, I'm going to be pedantic and 
be absolutely firm on the difference:

class MyPseudoIterator:
    def __iter__(self):
        return iter(some data)


(It's not a true iterator, because it doesn't return self. Instead, it 
returns a true iterator. But 95% of the time, we don't care too much 
about the difference.)

Sometimes you already have a bunch of data ready to use, like a list, 
and calling iter() is easy. But sometimes you want to calculate the data 
on the fly, and that's where Eryksun's suggestion to use a generator is 
specially useful:


class MyPseudoIterator:
    def __iter__(self):
        # use "yield" instead of "return"
        yield "something"
        yield "another thing"
        result = calculate_stuff()
        yield result


Notice that in both cases I don't declare a __next__ method! That's 
because I never call next() on MyPseudoIterator instances directly, I 
always call iter() first:

# this won't work
instance = MyPseudoIterator()
result = next(instance)  # fails

# this does
instance = MyPseudoIterator()
it = iter(instance)
result = next(it)  # works


For-loops are okay since Python automatically calls iter for you:

instance = MyPseudoIterator()
for item in instance:
    ...


> Second: you state that I don't have to worry about the name
> difference, but when I changed the method name from next to __next__
> it worked in 3.3. So what's your point here?

I think that Eryksun means that in Python 2, you can call:

it.next()

but in Python 3 you can call:

it.__next__()

but neither are recommended, instead you should call:

next(it)

and let the built-in next() function worry about the difference.



-- 
Steven

From eryksun at gmail.com  Fri Jan 24 07:56:29 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 24 Jan 2014 01:56:29 -0500
Subject: [Tutor] iter class
In-Reply-To: <20140124004348.GO3915@ando>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <CABicbJKK0LGJL1HKjjoey1akRGJ35Ddndz=S_dLVmDYNqzy5rA@mail.gmail.com>
 <CAO5ffbbBrbf7JVx0EgLaGpRythAyBjkvHewAvKDiprH2_jSrtg@mail.gmail.com>
 <CACL+1aumU0_OZ2_ybr9Aw8bnos7nQeUP0axWVnLPGujebXGkgA@mail.gmail.com>
 <CAO5ffbaHNTYSpE48ZbRPmfc0AjS2_1FHaF2HEAj2WyDK1VEwDg@mail.gmail.com>
 <20140124004348.GO3915@ando>
Message-ID: <CACL+1au1_yOwCu-N2Z2Gk0W9bqT7gr2qgDqEn+gSR33X+z3aGw@mail.gmail.com>

On Thu, Jan 23, 2014 at 7:43 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> Generators are a kind of function, which are special. You can't inherit
> from them:

I clarified my sloppy language in a reply. `__iter__` should be a
generator function, not a generator. A generator function uses `yield`
and `yield from` expressions, and returns a `generator` when called.
In CPython, the code for a generator function is flagged as
CO_GENERATOR:

    def genfun():
        yield 1

    flags = genfun.__code__.co_flags

    >>> inspect.CO_GENERATOR
    32
    >>> flags & inspect.CO_GENERATOR
    32

But that's CPython specific; use the inspect API instead (2.6+):

    >>> inspect.isgeneratorfunction(genfun)
    True

A "generator expression" also creates a generator. In CPython, this is
implemented by calling an anonymous generator function that gets
instantiated and called automagically.

When a function is called, the interpreter creates a frame to evaluate
the function's bytecode, given the function's globals and the current
thread state. It combines the call's positional and keyword arguments
with the `__defaults__` tuple and `__kwdefaults__` dict to set the
parameters as local variables in the frame. For a closure, it also
loads the free-variable `cell` objects from the `__closure__` tuple.
Everything is ready to call PyEval_EvalFrameEx to evaluate the
frame...

Except if the code is flagged as CO_GENERATOR that doesn't happen.
Instead the interpreter creates and returns a `generator` that
references the frame as its `gi_frame` attribute. Calling the
generator's `__next__` method in turn evaluates the frame up to a
`yield` or `yield from` expression. `StopIteration` is raised when the
frame executes a `return` statement or explicit `return None` -- or
implicitly returns from the last line of the function.

Like the function type, the generator type is finalized (i.e. doesn't
allow subclassing). It's clear why that would be the case for the type
of a singleton object such as None, Ellipsis, NotImplemented, and
True/False (bool). In other cases, supporting subclassing would be
more work (initial coding, bugs, maintenance -- who's volunteering?)
for little gain. For example: slice and range. Other types are so
closely linked to the language that I don't see why anyone would care
to subclass them, such as function, method, generator, frame, code,
and cell [1]. There's a fuzzy line there; property, classmethod, and
staticmethod aren't finalized.

[1] Listing every finalized type in CPython would be tedious. Here's a
few more, if anyone cares: builtin_function_or_method,
method_descriptor, classmethod_descriptor, member_descriptor,
getset_descriptor, wrapper_descriptor, and method-wrapper.

From asanch505 at hotmail.com  Fri Jan 24 03:34:18 2014
From: asanch505 at hotmail.com (Tobias Quezada)
Date: Thu, 23 Jan 2014 19:34:18 -0700
Subject: [Tutor] code works in windows command but not ubuntu terminal
Message-ID: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>

hello community,i am a newbie to python and program in general.
the script below works in python 2.7.3 on windows but not in the python 2.7.3 ubuntu terminal.

>>>fp=open("prez.dat","r")>>>x=fp.read>>>(print(x)***i used fp for file pointer.I am using windows 7 and it works but on ubuntu 12.04 LTS i get this syntax error:
Traceback (most recent call last):  File "<stdin>", line 1, in <module>IOError: [Errno 2] No such file or directory: 'prez.dat'

Any thoughts?Thanx 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140123/b81e87d8/attachment.html>

From __peter__ at web.de  Fri Jan 24 10:22:15 2014
From: __peter__ at web.de (Peter Otten)
Date: Fri, 24 Jan 2014 10:22:15 +0100
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
Message-ID: <lbtbaa$lpe$1@ger.gmane.org>


+----------+--------------------+------------------------+
|          | __iter__           | __next__               |
+----------+--------------------+------------------------+
| iterable | return an iterator | not available          |
+----------+--------------------+------------------------+
| iterator | return self        | return next item       |
|          |                    | or raise StopIteration |
+----------+--------------------+------------------------+

iter(x) is x --> True:      x is an iterator
                 False:     x is an iterable
                 raises Exception: x is neither iterator nor iterable

Once next(it) raises a StopIteration on a well-behaved iterator it must 
continue to raise `StopIteration`s on subsequent next(it) calls.

There's an odd outlier that I probably shouldn't tell you about: 
classes with a __getitem__() method behave like iterators. An eventual 
IndexError exception is propagated as StopIteration:

>>> class A:
...     def __getitem__(self, index):
...             if index > 2:
...                     raise IndexError
...             return index * index
... 
>>> for item in A():
...     print(item)
... 
0
1
4



From keithwins at gmail.com  Fri Jan 24 10:22:20 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 24 Jan 2014 04:22:20 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
Message-ID: <CAO5ffbbzFpWhynt2E9nVmwC8yeBYY9ifHXiacms8LmaovOV=9A@mail.gmail.com>

The file would appear to not be on your search path, that is, in any
directory in which Python is expecting to find it. Either move it to a
directory on your path, or change your path to include it's location.
The easiest way to find out what your path is, that I know, is

import sys
sys.path

Good luck! Warning, I'm still a beginner myself, I might be mistaken
about something... If you don't understand what I'm talking about, try
to be very specific about what you do understand, it'll help people
formulate clear responses.

From keithwins at gmail.com  Fri Jan 24 10:23:08 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 24 Jan 2014 04:23:08 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <CAO5ffbbzFpWhynt2E9nVmwC8yeBYY9ifHXiacms8LmaovOV=9A@mail.gmail.com>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <CAO5ffbbzFpWhynt2E9nVmwC8yeBYY9ifHXiacms8LmaovOV=9A@mail.gmail.com>
Message-ID: <CAO5ffbbKeWHrGW2BVSmZM-Wguv=3VeWmJ_w_gS_fW2Wa4NZr_g@mail.gmail.com>

I should have mentioned, the other possibility is that the file does
not, in fact, exist, but I assume you put it out there somewhere?

From __peter__ at web.de  Fri Jan 24 10:31:10 2014
From: __peter__ at web.de (Peter Otten)
Date: Fri, 24 Jan 2014 10:31:10 +0100
Subject: [Tutor] code works in windows command but not ubuntu terminal
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
Message-ID: <lbtbr0$s3m$1@ger.gmane.org>

Tobias Quezada wrote:

> hello community,i am a newbie to python and program in general.
> the script below works in python 2.7.3 on windows but not in the python
> 2.7.3 ubuntu terminal.
> 
>>>>fp=open("prez.dat","r")>>>x=fp.read>>>(print(x)***i used fp for file
>>>>pointer.I am using windows 7 and it works but on ubuntu 12.04 LTS i get
>>>>this syntax error:
> Traceback (most recent call last):  File "<stdin>", line 1, in
> <module>IOError: [Errno 2] No such file or directory: 'prez.dat'
 
That was probably

> fp=open("prez.dat","r")
> x=fp.read
> print(x)


> i used fp for file pointer.I am using windows 7 and it works but on ubuntu
> 12.04 LTS i get this syntax error:

> Traceback (most recent call last):  File "<stdin>", line 1, in
> <module>IOError: [Errno 2] No such file or directory: 'prez.dat'
> Any thoughts?Thanx

Please reread the error message. This is not a SyntaxError. Python is trying 
to tell you that a file called "prez.dat" doesn't exist in the current 
working directory. However, once you create the file (or provide the 
complete path if the file exists but is located in another directory) you 
will run into the next problem:

> x=fp.read

This will bind x to the fp.read method. To call the method the parentheses 
are mandatory:

x = fp.read()


From steve at pearwood.info  Fri Jan 24 10:47:36 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Jan 2014 20:47:36 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
Message-ID: <20140124094735.GQ3915@ando>

Hi Tobias, and welcome.

On Thu, Jan 23, 2014 at 07:34:18PM -0700, Tobias Quezada wrote:
> hello community,i am a newbie to python and program in general.
> the script below works in python 2.7.3 on windows but not in the python 2.7.3 ubuntu terminal.
> 
> >>> fp=open("prez.dat","r")
> >>> x=fp.read
> >>> (print(x)
>
> ***i used fp for file pointer.I am using windows 7 and it works

Are you sure this is the *exact* same code you use on Windows 7? Because 
it won't read the file, it will fail with a SyntaxError due to the 
missing close bracket after the print. 

Fixing that problem reveals another problem: rather than read the 
file, it will just print something like 
this:

<built-in method read of _io.TextIOWrapper object at 0xb7b6911c>

That's because you need round brackets (parentheses) to actually call 
the read method, otherwise you just get the method itself.

Finally we get to the error you have have reported:

> but on ubuntu 12.04 LTS i get this syntax error:
> Traceback (most recent call last):  
> File "<stdin>", line 1, in <module>
> IOError: [Errno 2] No such file or directory: 'prez.dat'

That's not a syntax error. The problem is not with your code, but with 
the location of the file. There is no file called "prez.dat" in the 
current directory.

Possibly you have just forgotten to create the file, or you have 
forgotten that Ubuntu (like all Linux operating systems) are case 
sensitive and "prez.dat" will not match "Prez.DAT", or the file is in 
the wrong directory. You may need to use the cd command to go into the 
directory before starting Python.

Does this help solve your problem? Please feel free to ask if you have 
any further questions.


-- 
Steven

From steve at pearwood.info  Fri Jan 24 10:50:25 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 24 Jan 2014 20:50:25 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <CAO5ffbbzFpWhynt2E9nVmwC8yeBYY9ifHXiacms8LmaovOV=9A@mail.gmail.com>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <CAO5ffbbzFpWhynt2E9nVmwC8yeBYY9ifHXiacms8LmaovOV=9A@mail.gmail.com>
Message-ID: <20140124095025.GR3915@ando>

On Fri, Jan 24, 2014 at 04:22:20AM -0500, Keith Winston wrote:
> The file would appear to not be on your search path, that is, in any
> directory in which Python is expecting to find it.

Python does not use a search path for the open() function, only for 
imports. With open(), it uses a simple rule:

- absolute paths will look only in that exact location;

- relative paths are always relative to the current working directory.

Do you know the difference between absolute and relative paths?


-- 
Steven

From maxint64 at gmail.com  Fri Jan 24 10:16:54 2014
From: maxint64 at gmail.com (maxint64 at gmail.com)
Date: Fri, 24 Jan 2014 17:16:54 +0800
Subject: [Tutor] code works in windows command but not ubuntu terminal
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
Message-ID: <201401241716449522520@gmail.com>

hello community,i am a newbie to python and program in general.
the script below works in python 2.7.3 on windows but not in the python 2.7.3 ubuntu terminal.

>>>fp=open("prez.dat","r")>>>x=fp.read>>>(print(x)***i used fp for file pointer.I am using windows 7 and it works but on ubuntu 12.04 LTS i get this syntax error:
Traceback (most recent call last):  File "<stdin>", line 1, in <module>IOError: [Errno 2] No such file or directory: 'prez.dat'

Any thoughts?Thanx 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140124/0aea68e0/attachment.html>

From alan.gauld at btinternet.com  Fri Jan 24 14:04:31 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 24 Jan 2014 13:04:31 +0000
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
Message-ID: <lbtocj$hgm$1@ger.gmane.org>

On 24/01/14 02:34, Tobias Quezada wrote:

>  >>>fp=open("prez.dat","r")
>  >>>x=fp.read
>  >>>(print(x)

> /IOError: [Errno 2] No such file or directory: 'prez.dat'/

Python can't see your file. You can check what python
is seeing by importing os and using listdir():

import os
os.listdir(',')  # . is the current directory

If your file is not listed then that's your problem.
Or it could be a permissions problem, but I can't
recall if that's a different error message, I suspect
so.

hth
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From denis.spir at gmail.com  Fri Jan 24 14:50:15 2014
From: denis.spir at gmail.com (spir)
Date: Fri, 24 Jan 2014 14:50:15 +0100
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
In-Reply-To: <lbtbaa$lpe$1@ger.gmane.org>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <lbtbaa$lpe$1@ger.gmane.org>
Message-ID: <52E26F97.5090503@gmail.com>

On 01/24/2014 10:22 AM, Peter Otten wrote:
>
> There's an odd outlier that I probably shouldn't tell you about [...]

I guess there is a whole class of outliers; not really sure how to classify 
them. This is the case of defining a wrapper or "proxy" type, for a underlying 
data structure which is iterable, typically a builtin collection. This was 
evoked (but not specifically termed as "wrapper" or such) in previous message of 
the orginal thread. In that case, __iter__ would neither return self (it is not 
an iterator), nore a hand-baked iterator, but the builtin (or already defined) 
one of the underlying iterable. Two example, rather artificial (but code works):

First, say you have an array of angles, which for the user are measured in 
degrees but internally use radians. (A better example may be of internal 
machine-friendly RGB colors and external user-friendly HSL colors [not HSV! 
grrrr...].) At the interface, there is conversion. Iteration actually is 
iterating on the internal array, thus just uses iter().

import math ; TAU = 2 * math.pi
class Angles:
     def __init__ (self):
         self.angles = list()
     def put (self, angle):
         self.angles.append(angle * TAU / 360)
     def __getitem__ (self, i):
         return self.angles[i] * 360 / TAU
     def __iter__ (self):
         return iter(self.angles)

angles = Angles()
angles.put(100) ; angles.put(200) ; angles.put(300)
print(angles[1])
for a in angles: print(a)

Second, we build an associative array (for few entries) as a plain association 
list ? la Lisp, but implemented as a pair of lists instead as a list of pairs 
(this saves an intermediate notion of Pair). Iterating is here on the pair of 
list, zipped (in the python sense) together:

class AssList:
     def __init__ (self):
         self.keys, self.vals = list(), list()
     def put (self, key, val):
         self.keys.append(key)
         self.vals.append(val)
     def __getitem__ (self, i):
         return self.keys[i], self.vals[i]
     def __iter__ (self):
         return iter(zip(self.keys, self.vals))

al = AssList()
al.put(1,'a') ; al.put(2,'b') ; al.put(3,'c')
print(al[1])
for k,v in al: print(k,v)

Side question: what is the point of __iter__ on iterators? Take a 'for' loop like:
	for x in xs: f(x)
In the case where xs is not an iterator (no __next__), python calls iter(xs), 
which IIUC may call xs.__iter__() unless it is a builtin. But if xs is an 
iterator (__next__ is there), then Python uses it directly, thus what is the 
point of __iter__ there? In any case, python must check whether xs is an 
iterator (__next__). So there is no sense in calling __iter__ on an iterator. 
Logically, this would lead to an infinite recursion (calling __iter__ again and 
again). But python does it anyway (and stops after the first call, indeed):

class Iter:
     def __init__ (self): self.n = 0
     def __next__ (self):
         if self.n == 10: raise StopIteration
         self.n += 1
         return self.n
     def __iter__ (self):
         print("*** __iter__ ***")		# *********
         return self
it = Iter()
for i in it: print(i, end=" ")
print()

huh?

The only theoretical case I can find is iterators which do implement the 
protocol (__next__) but are not to be used (!), instead delegate to another 
iterator. Then, why do they bear __next__ at all? why are they iterators at all?

denis

From __peter__ at web.de  Fri Jan 24 18:44:31 2014
From: __peter__ at web.de (Peter Otten)
Date: Fri, 24 Jan 2014 18:44:31 +0100
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <lbtbaa$lpe$1@ger.gmane.org> <52E26F97.5090503@gmail.com>
Message-ID: <lbu8pj$4rp$1@ger.gmane.org>

spir wrote:

> On 01/24/2014 10:22 AM, Peter Otten wrote:
>>
>> There's an odd outlier that I probably shouldn't tell you about [...]
> 
> I guess there is a whole class of outliers; not really sure how to
> classify them. 

I think you are focusing on the details too much. In

> class Angles:
>      def __getitem__ (self, i):
>          return self.angles[i] * 360 / TAU
>      def __iter__ (self):
>          return iter(self.angles)

iter(self.angles) is just an implementation detail. The important point is 
that __iter__() returns a new iterator on each invocation, thus making 
Angles an "iterable" according to the naming scheme I was trying to 
establish. The __getitem__() method can be ignored as it is used for element 
lookup only, not for iteration.

    
> Side question: what is the point of __iter__ on iterators? Take a 'for'
> loop like: for x in xs: f(x)
> In the case where xs is not an iterator (no __next__), python calls
> iter(xs), which IIUC may call xs.__iter__() unless it is a builtin. But if
> xs is an iterator (__next__ is there), then Python uses it directly, thus
> what is the point of __iter__ there? In any case, python must check
> whether xs is an iterator (__next__). So there is no sense in calling
> __iter__ on an iterator. Logically, this would lead to an infinite
> recursion (calling __iter__ again and again). But python does it anyway
> (and stops after the first call, indeed):

There is no infinite recursion. The for loop is currently implemented as

# expect an iterable
# handle iterators through an idempotent iter()
tmp = iter(xs)
while True:
    try:
        x = next(tmp)
    except StopIteration:
        break
    # use x

If I understand you correctly you suggest the following:

# expect an iterator
# fall back to getting an iterator through iter()
try:
    tmp = xs.__next__
except AttributeError:
    tmp = iter(xs).__next__
while True:
    try:
        x = tmp()
    except StopIteration:
        break

How is that simpler?

> The only theoretical case I can find is iterators which do implement the
> protocol (__next__) but are not to be used (!), instead delegate to
> another iterator. 

Again: the important differentiation is between iterator and iterable, not 
how the iterator is implemented.

> Then, why do they bear __next__ at all? why are they
> iterators at all?

Python allows you to do things that make no sense from the point of view of 
a human being. You can also implement an integer type with a negative abs():

>>> class Int(int):
...     def __abs__(self): return self
... 
>>> abs(Int(-1))
-1

My advice: don't do it unless you have a good reason.


From keithwins at gmail.com  Fri Jan 24 22:31:49 2014
From: keithwins at gmail.com (Keith Winston)
Date: Fri, 24 Jan 2014 16:31:49 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140124095025.GR3915@ando>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <CAO5ffbbzFpWhynt2E9nVmwC8yeBYY9ifHXiacms8LmaovOV=9A@mail.gmail.com>
 <20140124095025.GR3915@ando>
Message-ID: <CAO5ffbb-FV6vEQWVmYhgxdSrQwVXQCxokKMzEwwrT5HrMTdoCA@mail.gmail.com>

On Fri, Jan 24, 2014 at 4:50 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> Python does not use a search path for the open() function, only for
> imports. With open(), it uses a simple rule:
>
> - absolute paths will look only in that exact location;
>
> - relative paths are always relative to the current working directory.
>
> Do you know the difference between absolute and relative paths?

Ah! I was just running into this... I did not know that. So there's no
way to get it to search a path (other than coding some string
concatenation of path names or something, of course) to open a file?
Well, at least that clears things up for me, I've stumbled over this a
few times and didn't understand. Thanks.


-- 
Keith

From denis.spir at gmail.com  Fri Jan 24 23:23:26 2014
From: denis.spir at gmail.com (spir)
Date: Fri, 24 Jan 2014 23:23:26 +0100
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
In-Reply-To: <lbu8pj$4rp$1@ger.gmane.org>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <lbtbaa$lpe$1@ger.gmane.org> <52E26F97.5090503@gmail.com>
 <lbu8pj$4rp$1@ger.gmane.org>
Message-ID: <52E2E7DE.9020001@gmail.com>

On 01/24/2014 06:44 PM, Peter Otten wrote:
> There is no infinite recursion. The for loop is currently implemented as
>
> # expect an iterable
> # handle iterators through an idempotent iter()
> tmp = iter(xs)

# here you must check that tmp actually implements the iterator protocol,
# else raise an error

> while True:
>      try:
>          x = next(tmp)
>      except StopIteration:
>          break
>      # use x
>
> If I understand you correctly you suggest the following:
>
> # expect an iterator
> # fall back to getting an iterator through iter()
> try:
>      tmp = xs.__next__
> except AttributeError:
>      tmp = iter(xs).__next__
> while True:
>      try:
>          x = tmp()
>      except StopIteration:
>          break
>
> How is that simpler?

see above

d

From dyoo at hashcollision.org  Fri Jan 24 23:26:30 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Fri, 24 Jan 2014 14:26:30 -0800
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <CAO5ffbb-FV6vEQWVmYhgxdSrQwVXQCxokKMzEwwrT5HrMTdoCA@mail.gmail.com>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <CAO5ffbbzFpWhynt2E9nVmwC8yeBYY9ifHXiacms8LmaovOV=9A@mail.gmail.com>
 <20140124095025.GR3915@ando>
 <CAO5ffbb-FV6vEQWVmYhgxdSrQwVXQCxokKMzEwwrT5HrMTdoCA@mail.gmail.com>
Message-ID: <CAGZAPF5Lgk+ogHQGCAw1CPQnbbiyffPckuP9a5+0B55O4Y7cUw@mail.gmail.com>

> Ah! I was just running into this... I did not know that. So there's no
> way to get it to search a path (other than coding some string
> concatenation of path names or something, of course) to open a file?

Potentially distutils.spawn.find_executable might apply,

    http://docs.python.org/2/distutils/apiref.html#module-distutils.spawn

but this it is not intended for finding data files either.


If you really need something like this, you'll probably be writing
your own path searching routines for this, as to my knowledge this is
not provided by the standard library.

(Probably for a good reason: sometimes searching for a data resource
without knowing exactly where it should be can be a susceptible vector
for attacks.  That is, you might consider this a convenience vs.
safety thing.  Directory search can be _expensive_ in certain contexts
as well, such as on a networked file system, for example.)

---

In a professional context: there are libraries in place where you say
explicitly which resources your file depends on at installation time,
and the library manages the placement and finding of those resources
at runtime.  For an example, see the distutils.package_data option:

    http://docs.python.org/2/distutils/setupscript.html#installing-package-data

From imtherealleon at gmail.com  Fri Jan 24 18:57:04 2014
From: imtherealleon at gmail.com (Leon S)
Date: Fri, 24 Jan 2014 12:57:04 -0500
Subject: [Tutor] How to correct decimal addition.
Message-ID: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>

Here is what I'm trying to do, accept a price of gas, but I want to add the
.009 to the price, so that people do not have to type the full amount.
 Example, 3.49 /gallon would return 3.499 /gallon.

This is what I have tried and the results of it.

def gas_price(price):
   price == raw_input("What is the price of gas?")  return price + .09
  3.49=> 3.4899999999999998


It reduces the number and then adds many decimal points after.


Thanks for any help, I am sure this is an easy one for someone.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140124/3cf9aca3/attachment.html>

From norman at khine.net  Fri Jan 24 23:44:18 2014
From: norman at khine.net (Norman Khine)
Date: Fri, 24 Jan 2014 22:44:18 +0000
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
Message-ID: <CAKgQ7U+L6Fs0QyeHv4_h8RQsA5bcBXHtAqTeQBe4KQfaSsQEzQ@mail.gmail.com>

maybe this would be of help

https://stackoverflow.com/questions/455612/python-limiting-floats-to-two-decimal-points


On Fri, Jan 24, 2014 at 5:57 PM, Leon S <imtherealleon at gmail.com> wrote:

> Here is what I'm trying to do, accept a price of gas, but I want to add
> the .009 to the price, so that people do not have to type the full amount.
>  Example, 3.49 /gallon would return 3.499 /gallon.
>
> This is what I have tried and the results of it.
>
> def gas_price(price):
>    price == raw_input("What is the price of gas?")  return price + .09   3.49=> 3.4899999999999998
>
>
> It reduces the number and then adds many decimal points after.
>
>
> Thanks for any help, I am sure this is an easy one for someone.
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>


-- 
%>>> "".join( [ {'*':'@','^':'.'}.get(c,None) or chr(97+(ord(c)-83)%26) for
c in ",adym,*)&uzq^zqf" ] )
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140124/1d2e3c87/attachment.html>

From wescpy at gmail.com  Sat Jan 25 01:34:52 2014
From: wescpy at gmail.com (wesley chun)
Date: Fri, 24 Jan 2014 16:34:52 -0800
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
Message-ID: <CAB6eaA4QFO-20XrO46grUC5yYDR1cpPfZntvzpa-E1nnZMF+OQ@mail.gmail.com>

hi leon,

you made a good start and ran into something that i know doesn't seem right
to you. however, before we attack the issue, there are some basic problems
with the code you need to correct first. below are a few explanations and
perhaps workarounds:

   1. you're passing in price *and* asking the user for it... pick one, not
   both
   2. i'll assume you did *not* mean to pass it in for the rest of this
   response
   3. the == should be a single = otherwise you should get a NameErrorexception
   4. the return price + .09 should be indented on the next line
   5. the operation price + .09 should fail with a TypeError exception
   6. the value .09 is incorrect for the solution you're describing...
   choose another
   7. assuming you fix all of the problems above and run it, you'll still
   get the output you stated
   8. however, if you print the value, it'll show correctly
   9. if you use Python 2.7.x+ or 3.1.x+, it'll show correctly
   10. reference link 1 to review:
   http://docs.python.org/tutorial/floatingpoint
   11. reference link 2 to review: http://bugs.python.org/issue1580

hope this helps!
--wesley


On Fri, Jan 24, 2014 at 9:57 AM, Leon S <imtherealleon at gmail.com> wrote:

> Here is what I'm trying to do, accept a price of gas, but I want to add
> the .009 to the price, so that people do not have to type the full amount.
>  Example, 3.49 /gallon would return 3.499 /gallon.
>
> This is what I have tried and the results of it.
>
> def gas_price(price):
>    price == raw_input("What is the price of gas?")  return price + .09   3.49=> 3.4899999999999998
>
>
> It reduces the number and then adds many decimal points after.
>
>
> Thanks for any help, I am sure this is an easy one for someone.
>
>


-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"A computer never does what you want... only what you tell it."
    +wesley chun <http://google.com/+WesleyChun> : wescpy at gmail :
@wescpy<http://twitter.com/wescpy>
    Python training & consulting : http://CyberwebConsulting.com
    "Core Python" books : http://CorePython.com
    Python blog: http://wescpy.blogspot.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140124/05906879/attachment-0001.html>

From davea at davea.name  Sat Jan 25 01:39:41 2014
From: davea at davea.name (Dave Angel)
Date: Fri, 24 Jan 2014 19:39:41 -0500 (EST)
Subject: [Tutor] How to correct decimal addition.
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
Message-ID: <lbv0vb$1if$1@ger.gmane.org>

 Leon S <imtherealleon at gmail.com> Wrote in message:
> _

(please post in plain text in this text mailing list.  Html messes
 up formatting and causes some newsreaders grief.)
......................
Leon said:
Here is what I'm trying to do, accept a price of gas, but I want
 to add the .009 to the price, so that people do not have to type
 the full amount. ??Example, 3.49 /gallon would return 3.499
 /gallon.

This is what I have tried and the results of it.

def gas_price(price):  
   price == raw_input("What is the price of gas?")  return price + .09
   3.49
=> 3.4899999999999998

It reduces the number and then adds many decimal points after.

Thanks for any help, I am sure this is an easy one for someone
..............................

That stackoverflow link has lots of good information and some
 disinformation. 

First the code you show won't run, even after fixing the
 formatting.  Please use copy/paste. But making some assumptions, 
 I'm guessing you're adding two float objects and wondering why
 the result is off when printed. 

float is a binary floating point object and cannot represent
 precisely decimal float values like three point forty nine. You
 get quantization errors by definition,  and must deal with them
 somehow before the user sees them. You can fix that either by not
 using binary (perhaps the decimal module? ) or by rounding when
 you convert to string before printing. 

Next time, post in text format, include all your code (no print or
 equivalent in what you posted ), and tell us what version of
 python you're using. 



> 


-- 
DaveA


From steve at pearwood.info  Sat Jan 25 02:38:18 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 25 Jan 2014 12:38:18 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <CAO5ffbb-FV6vEQWVmYhgxdSrQwVXQCxokKMzEwwrT5HrMTdoCA@mail.gmail.com>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <CAO5ffbbzFpWhynt2E9nVmwC8yeBYY9ifHXiacms8LmaovOV=9A@mail.gmail.com>
 <20140124095025.GR3915@ando>
 <CAO5ffbb-FV6vEQWVmYhgxdSrQwVXQCxokKMzEwwrT5HrMTdoCA@mail.gmail.com>
Message-ID: <20140125013818.GU3915@ando>

On Fri, Jan 24, 2014 at 04:31:49PM -0500, Keith Winston wrote:
> On Fri, Jan 24, 2014 at 4:50 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> > Python does not use a search path for the open() function, only for
> > imports. With open(), it uses a simple rule:
> >
> > - absolute paths will look only in that exact location;
> >
> > - relative paths are always relative to the current working directory.
> >
> > Do you know the difference between absolute and relative paths?
> 
> Ah! I was just running into this... I did not know that. So there's no
> way to get it to search a path (other than coding some string
> concatenation of path names or something, of course) to open a file?

Of course there is -- you just have to program it yourself!

First, decide whether the filename is absolute or relative. Absolute 
filenames should not search the path. Then, if it is relative, loop over 
your "open path list" like this:


for prefix in open_path_list:
    location = os.path.join(prefix, filename)
    try:
        f = open(location)
    except IOError:
        pass
    else:
        break


However, there's more to it than this. For starters, you need to decide 
on the exact behaviour. Clearly, "file not found" errors should move on 
to try the next prefix in the path list. But what about permission 
denied errors? 



-- 
Steven

From eryksun at gmail.com  Sat Jan 25 04:13:47 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 24 Jan 2014 22:13:47 -0500
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
In-Reply-To: <52E26F97.5090503@gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <lbtbaa$lpe$1@ger.gmane.org> <52E26F97.5090503@gmail.com>
Message-ID: <CACL+1at1EVerAzJiWzYmjnFZ=9DxVppCFFTPEH_fvnrQ_v-k3g@mail.gmail.com>

On Fri, Jan 24, 2014 at 8:50 AM, spir <denis.spir at gmail.com> wrote:
>
> xs is an iterator (__next__ is there), then Python uses it directly, thus
> what is the point of __iter__ there? In any case, python must check whether

Python doesn't check whether a type is already an iterator. It's
simpler to require that iterators implement __iter__, like any other
non-sequence iterable. This technically allows an iterator to return a
new iterator when __iter__ is called:

    class C:
        def __iter__(self): return D()
        def __next__(self): return 'C'

    class D:
        def __iter__(self): return C()
        def __next__(self): return 'D'

    it1 = iter(C())
    it2 = iter(it1)

    >>> next(it1)
    'D'
    >>> next(it2)
    'C'

That said, it's supposed to return self.

From bgailer at gmail.com  Sat Jan 25 04:28:09 2014
From: bgailer at gmail.com (bob gailer)
Date: Fri, 24 Jan 2014 22:28:09 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140124094735.GQ3915@ando>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <20140124094735.GQ3915@ando>
Message-ID: <52E32F49.1030102@gmail.com>

On 1/24/2014 4:47 AM, Steven D'Aprano wrote:
> Hi Tobias, and welcome.
>
> On Thu, Jan 23, 2014 at 07:34:18PM -0700, Tobias Quezada wrote:
>> hello community,i am a newbie to python and program in general.
>> the script below works in python 2.7.3 on windows but not in the python 2.7.3 ubuntu terminal.
>>
>>>>> fp=open("prez.dat","r")
>>>>> x=fp.read
>>>>> (print(x)
>> ***i used fp for file pointer.I am using windows 7 and it works
> Are you sure this is the *exact* same code you use on Windows 7? Because
> it won't read the file, it will fail with a SyntaxError due to the
> missing close bracket after the print.
This is Python 2.7.3, not 3.x. The error is due to a ( in front of the 
print statement.

And please call () parends and [] brackets, and{} braces. Saves a lot of 
confusion.


From steve at pearwood.info  Sat Jan 25 05:14:40 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 25 Jan 2014 15:14:40 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E32F49.1030102@gmail.com>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
Message-ID: <20140125041440.GV3915@ando>

On Fri, Jan 24, 2014 at 10:28:09PM -0500, bob gailer wrote:

> And please call () parends and [] brackets, and{} braces. Saves a lot of 
> confusion.

If you think that parentheses are spelt with a "d", you're certainly 
confused :-)

They're all brackets. Often the type of bracket doesn't matter, but when 
it does, adjectives do a perfectly fine job at distinguishing one from 
the other: round brackets, square brackets, and curly brackets are 
well-known and in common use all over the Commonwealth, and have been 
established since the mid 1700s.

As a sop to Americans, who I understand are easily confused by ordinary 
English *wink*, the Unicode consortium describes () as parentheses:

py> unicodedata.name("(")
'LEFT PARENTHESIS'

but [] and {} are described as brackets:

py> unicodedata.name("[")
'LEFT SQUARE BRACKET'
py> unicodedata.name("{")
'LEFT CURLY BRACKET'

As are angle brackets:

py> unicodedata.lookup("LEFT ANGLE BRACKET")
'?'
py> unicodedata.lookup("RIGHT ANGLE BRACKET")
'?'

HTML uses ASCII less-than and greater-than signs as angle brackets.

Physicists even have a pun about them, with "bra-ket" notation for 
quantum state:

http://en.wikipedia.org/wiki/Bra-ket_notation

There are a number of other types of brackets with more specialised 
uses, or common in Asian texts. See http://en.wikipedia.org/wiki/Bracket

By the way, the word "bracket" itself is derived from the French and 
Spanish words for "codpiece". That's not relevant to anything, I just 
thought I'd mention it.


-- 
Steven

From eryksun at gmail.com  Sat Jan 25 05:27:46 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 24 Jan 2014 23:27:46 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140125013818.GU3915@ando>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <CAO5ffbbzFpWhynt2E9nVmwC8yeBYY9ifHXiacms8LmaovOV=9A@mail.gmail.com>
 <20140124095025.GR3915@ando>
 <CAO5ffbb-FV6vEQWVmYhgxdSrQwVXQCxokKMzEwwrT5HrMTdoCA@mail.gmail.com>
 <20140125013818.GU3915@ando>
Message-ID: <CACL+1av-wJELxdy9w-Zg7fyb7k=juRdH7Gz=-Pu3f_z_ayJaJw@mail.gmail.com>

On Fri, Jan 24, 2014 at 8:38 PM, Steven D'Aprano <steve at pearwood.info> wrote:
>
> However, there's more to it than this. For starters, you need to decide
> on the exact behaviour. Clearly, "file not found" errors should move on
> to try the next prefix in the path list. But what about permission
> denied errors?

Prior to 3.3, I/O operations raise an IOError, except functions in the
os module raise an OSError. Inspect the exception `errno` attribute
for the error code. Named error constants are available in the errno
module.

3.3 makes IOError an alias for OSError and maps several of the more
common error codes to subclasses that have descriptive names. Here are
some examples where 3.3 OSError returns a sublcass:

    >>> for code in [errno.EPERM, errno.ENOENT,
    ...              errno.EACCES, errno.EISDIR]:
    ...     OSError(code, os.strerror(code))
    ...
    PermissionError(1, 'Operation not permitted')
    FileNotFoundError(2, 'No such file or directory')
    PermissionError(13, 'Permission denied')
    IsADirectoryError(21, 'Is a directory')

From denis.spir at gmail.com  Sat Jan 25 08:49:51 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 25 Jan 2014 08:49:51 +0100
Subject: [Tutor] Iterator vs. iterable cheatsheet, was Re: iter class
In-Reply-To: <CACL+1at1EVerAzJiWzYmjnFZ=9DxVppCFFTPEH_fvnrQ_v-k3g@mail.gmail.com>
References: <CAO5ffba5Kex=AyjRJAPfRZGouAa0_eUL-kf56mL5MO8bJVCSBQ@mail.gmail.com>
 <lbtbaa$lpe$1@ger.gmane.org> <52E26F97.5090503@gmail.com>
 <CACL+1at1EVerAzJiWzYmjnFZ=9DxVppCFFTPEH_fvnrQ_v-k3g@mail.gmail.com>
Message-ID: <52E36C9F.7040101@gmail.com>

On 01/25/2014 04:13 AM, eryksun wrote:
> On Fri, Jan 24, 2014 at 8:50 AM, spir <denis.spir at gmail.com> wrote:
>>
>> xs is an iterator (__next__ is there), then Python uses it directly, thus
>> what is the point of __iter__ there? In any case, python must check whether
>
> Python doesn't check whether a type is already an iterator. It's
> simpler to require that iterators implement __iter__, like any other
> non-sequence iterable. This technically allows an iterator to return a
> new iterator when __iter__ is called:
>
>      class C:
>          def __iter__(self): return D()
>          def __next__(self): return 'C'
>
>      class D:
>          def __iter__(self): return C()
>          def __next__(self): return 'D'
>
>      it1 = iter(C())
>      it2 = iter(it1)
>
>      >>> next(it1)
>      'D'
>      >>> next(it2)
>      'C'
>
> That said, it's supposed to return self.

All right, thank you, Peter & Eryksun.

d


From denis.spir at gmail.com  Sat Jan 25 09:11:56 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 25 Jan 2014 09:11:56 +0100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140125041440.GV3915@ando>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <20140125041440.GV3915@ando>
Message-ID: <52E371CC.4030102@gmail.com>

On 01/25/2014 05:14 AM, Steven D'Aprano wrote:
> On Fri, Jan 24, 2014 at 10:28:09PM -0500, bob gailer wrote:
>
>> And please call () parends and [] brackets, and{} braces. Saves a lot of
>> confusion.
>
> If you think that parentheses are spelt with a "d", you're certainly
> confused :-)
>
> They're all brackets. Often the type of bracket doesn't matter, but when
> it does, adjectives do a perfectly fine job at distinguishing one from
> the other: round brackets, square brackets, and curly brackets are
> well-known and in common use all over the Commonwealth, and have been
> established since the mid 1700s.
>
> As a sop to Americans, who I understand are easily confused by ordinary
> English *wink*, the Unicode consortium describes () as parentheses:
>
> py> unicodedata.name("(")
> 'LEFT PARENTHESIS'
>
> but [] and {} are described as brackets:
>
> py> unicodedata.name("[")
> 'LEFT SQUARE BRACKET'
> py> unicodedata.name("{")
> 'LEFT CURLY BRACKET'
>
> As are angle brackets:
>
> py> unicodedata.lookup("LEFT ANGLE BRACKET")
> '?'
> py> unicodedata.lookup("RIGHT ANGLE BRACKET")
> '?'

As a foreigner, I noticed that english native speakers use both the series round 
/ square / curly / angle brackets, and individual terms parens (no 'd' ;-) / 
brackets / braces / chevrons. No major issue, except for 'brackets' which can be 
either a collective term or specific to [].

> HTML uses ASCII less-than and greater-than signs as angle brackets.
>
> Physicists even have a pun about them, with "bra-ket" notation for
> quantum state:
>
> http://en.wikipedia.org/wiki/Bra-ket_notation

funny

> There are a number of other types of brackets with more specialised
> uses, or common in Asian texts. See http://en.wikipedia.org/wiki/Bracket
>
> By the way, the word "bracket" itself is derived from the French and
> Spanish words for "codpiece". That's not relevant to anything, I just
> thought I'd mention it.

Apparently, according to wiktionary, it may come from an old germanic root 
through Gaulish:
https://en.wiktionary.org/wiki/bracket#Etymology
<< Etymology

 From earlier bragget, probably from Middle French braguette, from Old French 
braguette (?the opening in the fore part of a pair of breeches?), from Old 
Proven?al braga, from Latin br?ca (?pants?), from Transalpine Gaulish *br?ca 
(?pants?), perhaps from or related to similar forms in Germanic: compare Old 
English braccas (?pants?), Old English br?c (?breeches?), from 
Proto-Indo-European *b?r?g-, from *b?reg- (?to break, crack, split, divide?). 
More at breech, britches. >>

d



From denis.spir at gmail.com  Sat Jan 25 09:46:14 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 25 Jan 2014 09:46:14 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
Message-ID: <52E379D6.2050003@gmail.com>

On 01/24/2014 06:57 PM, Leon S wrote:
> Here is what I'm trying to do, accept a price of gas, but I want to add the
> .009 to the price, so that people do not have to type the full amount.
>   Example, 3.49 /gallon would return 3.499 /gallon.
>
> This is what I have tried and the results of it.
>
> def gas_price(price):
>     price == raw_input("What is the price of gas?")  return price + .09
>    3.49=> 3.4899999999999998
>
>
> It reduces the number and then adds many decimal points after.
>
>
> Thanks for any help, I am sure this is an easy one for someone.

This is instead easy for noone ;-)

The core issue is that for, say, "fractional numbers" (numbers with a fractional 
part, but unlike real numbers with definite precision) python like most 
programming languages uses in standard a binary representation internally. While 
we normally use decimal notation, both in input (reading) and output (writing). 
And there is no way to represent decimal fractions in binary, except in the very 
case where they are a multiple of an exact (negative) power of 2 (for instance 
1/2, 3/4, 123/128... are ok).

The only right solution is to use decimals internally, and python provides such 
a numeric type, Decimal:
http://docs.python.org/3/library/decimal.html

d

From denis.spir at gmail.com  Sat Jan 25 09:57:58 2014
From: denis.spir at gmail.com (spir)
Date: Sat, 25 Jan 2014 09:57:58 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <52E379D6.2050003@gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com>
Message-ID: <52E37C96.7040901@gmail.com>

On 01/25/2014 09:46 AM, spir wrote:
> On 01/24/2014 06:57 PM, Leon S wrote:
>> Here is what I'm trying to do, accept a price of gas, but I want to add the
>> .009 to the price, so that people do not have to type the full amount.
>>   Example, 3.49 /gallon would return 3.499 /gallon.
>>
>> This is what I have tried and the results of it.
>>
>> def gas_price(price):
>>     price == raw_input("What is the price of gas?")  return price + .09
>>    3.49=> 3.4899999999999998
>>
>>
>> It reduces the number and then adds many decimal points after.
>>
>>
>> Thanks for any help, I am sure this is an easy one for someone.
>
> This is instead easy for noone ;-)
>
> The core issue is that for, say, "fractional numbers" (numbers with a fractional
> part, but unlike real numbers with definite precision) python like most
> programming languages uses in standard a binary representation internally. While
> we normally use decimal notation, both in input (reading) and output (writing).
> And there is no way to represent decimal fractions in binary, except in the very
> case where they are a multiple of an exact (negative) power of 2 (for instance
> 1/2, 3/4, 123/128... are ok).
>
> The only right solution is to use decimals internally, and python provides such
> a numeric type, Decimal:
> http://docs.python.org/3/library/decimal.html

I did not read correctly. If you're dealing with financial as it seems, the 
right way is to use integers instead. Since you are adding tenth's of pence, 
this is what your unit means. Then your sum is:
	3490 + 9
:-)

Note: AFAIK most financial software use integers for this reason and to avoid 
(or control) rounding errors.

At input and/or output, you may still have to convert to Decimal to get 
"decimally correct" value or expression.

	numeral = input("...")
	value = Decimal(numeral)
	...
	output = Decimal(result) / Decimal("1000")
	print(output)

(not sure, not tried)

d

From breamoreboy at yahoo.co.uk  Sat Jan 25 14:50:20 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sat, 25 Jan 2014 13:50:20 +0000
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E32F49.1030102@gmail.com>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
Message-ID: <lc0feq$lk1$1@ger.gmane.org>

On 25/01/2014 03:28, bob gailer wrote:
>
> And please call () parends and [] brackets, and{} braces. Saves a lot of
> confusion.
>

Not in the UK or Australia, with the former being where English came from.

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

Mark Lawrence


From bgailer at gmail.com  Sat Jan 25 20:39:11 2014
From: bgailer at gmail.com (bob gailer)
Date: Sat, 25 Jan 2014 14:39:11 -0500
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E32F49.1030102@gmail.com>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
Message-ID: <52E412DF.5080603@gmail.com>

On 1/24/2014 10:28 PM, bob gailer wrote:

Sorry for misspelling parens.

My reason for requesting the various names is that it makes 
communication clear, explicit and terse.

When someone says just "brackets" what does he actually mean?

For more grins see 
http://www.codinghorror.com/blog/2008/06/ascii-pronunciation-rules-for-programmers.html
and http://www.theasciicode.com.ar/

From oscar.j.benjamin at gmail.com  Sat Jan 25 21:38:21 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Sat, 25 Jan 2014 20:38:21 +0000
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <52E37C96.7040901@gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
Message-ID: <CAHVvXxTUa5_TKdajw+i_xMX2mkxi3XC8bp3knjMEH8nXNrWrBw@mail.gmail.com>

On 25 January 2014 08:57, spir <denis.spir at gmail.com> wrote:
> On 01/25/2014 09:46 AM, spir wrote:
>>
>> On 01/24/2014 06:57 PM, Leon S wrote:
>>>
>>> Here is what I'm trying to do, accept a price of gas, but I want to add
>>> the
>>> .009 to the price, so that people do not have to type the full amount.
>>>   Example, 3.49 /gallon would return 3.499 /gallon.
>>>
>>> This is what I have tried and the results of it.
>>>
>>> def gas_price(price):
>>>     price == raw_input("What is the price of gas?")  return price + .09
>>>    3.49=> 3.4899999999999998
>>>
>>> It reduces the number and then adds many decimal points after.
>>>
>>> Thanks for any help, I am sure this is an easy one for someone.
>>
>> This is instead easy for noone ;-)
>>
>> The core issue is that for, say, "fractional numbers" (numbers with a
>> fractional
>> part, but unlike real numbers with definite precision) python like most
>> programming languages uses in standard a binary representation internally.
>> While
>> we normally use decimal notation, both in input (reading) and output
>> (writing).
>> And there is no way to represent decimal fractions in binary, except in
>> the very
>> case where they are a multiple of an exact (negative) power of 2 (for
>> instance
>> 1/2, 3/4, 123/128... are ok).
>>
>> The only right solution is to use decimals internally, and python provides
>> such
>> a numeric type, Decimal:
>> http://docs.python.org/3/library/decimal.html
>
> I did not read correctly. If you're dealing with financial as it seems, the
> right way is to use integers instead.

I would say that using Decimal is the "right" solution for financial
calculations. Using integers (AKA fixed-point arithmetic) is possible
and is the standard solution for languages that lack a Decimal type.

> Since you are adding tenth's of pence,
> this is what your unit means. Then your sum is:
>         3490 + 9
> :-)
>
> Note: AFAIK most financial software use integers for this reason and to
> avoid (or control) rounding errors.

The Decimal module allows you to avoid or control rounding errors. If
it is true that most financial software uses fixed-point arithmetic
instead of floating point decimal arithmetic then I would guess that
the most likely reason is that the language used for the software
doesn't have a library for floating point decimal arithmetic as Python
does.

A significant motivating use-case for adding the Decimal module and
for subsequently speeding it up with a C implementation was to support
using Python in the context of financial software.

> At input and/or output, you may still have to convert to Decimal to get
> "decimally correct" value or expression.
>
>         numeral = input("...")
>         value = Decimal(numeral)
>         ...
>         output = Decimal(result) / Decimal("1000")
>         print(output)
>
> (not sure, not tried)

I would do it like so:

>>> from decimal import Decimal
>>> def adjust_price(price):
...     return Decimal(price) + Decimal('.005')
...
>>> adjust_price('3.49')
Decimal('3.495')
>>> print(adjust_price('3.49'))
3.495

But then what happens if the use has added the .005 themselves:

>>> print(adjust_price('3.495'))
3.500

Perhaps we should round down before adding .005:

>>> from decimal import ROUND_DOWN
>>> def adjust_price(price):
...     # Round down to 2 decimal places
...     price = Decimal(price).quantize(Decimal('1.00'), rounding=ROUND_DOWN)
...     return price + Decimal('.005')
...
>>> print(adjust_price('3.49'))
3.495
>>> print(adjust_price('3.495'))
3.495

Of course now you'll get:

>>> print(adjust_price('3.497'))
3.495

Maybe that's not what was wanted either (I'm not sure exactly what you
do want in this case).


Oscar

From keithwins at gmail.com  Sat Jan 25 22:01:49 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 25 Jan 2014 16:01:49 -0500
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <52E37C96.7040901@gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
Message-ID: <CAO5ffbaAySvg1a3ALhWDMfjPVtJF+TiNYrV-E1t4Nb9L2u9Lfg@mail.gmail.com>

On Sat, Jan 25, 2014 at 3:57 AM, spir <denis.spir at gmail.com> wrote:
>> .009 to the price, so that people do not have to type the full amount.
>>   Example, 3.49 /gallon would return 3.499 /gallon.
>>
>> This is what I have tried and the results of it.
>>
>> def gas_price(price):
>>     price == raw_input("What is the price of gas?")  return price + .09
>>    3.49=> 3.4899999999999998

I think there's an inconsistency in your post that might confuse the
answers. You mention in the lead that you want to add 9 ONE HUNDREDTHS
of a dollar, or tenths of a cent (which is in fact how gas is priced
in the US, and yes it's crazy stupid). However in your example you add
only tenths, but then in the answer you appear to have added
hundredths, which makes me think that you didn't cut & paste, but
rather retyped (and mistyped).

This will make it a little trickier to use Denis' last idea of using
integers, since you'll have to take them out one more order of
magnitude. If this exercise is later followed by interest
calculations, or anything like that, you might regret limiting your
internal accuracy/representation.

I think that you should probably do your math in floating point (why
get complicated? And you might need the accuracy, for hundredths of
dollars and interest) and then format the output to be what you want.
Watch out for rounding.

>>> p = 3.499
>>> print('{0:.3f}'.format(p))   # format a float with 3 places after the decimal
3.499
>>> p = 3.4994
>>> print('{0:.3f}'.format(p))
3.499
>>> p = 3.4999999
>>> print('{0:.3f}'.format(p))
3.500

-- 
Keith

From keithwins at gmail.com  Sat Jan 25 22:19:55 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 25 Jan 2014 16:19:55 -0500
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <52E37C96.7040901@gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
Message-ID: <CAO5ffbYM2OzBZPdNYhW9bbVbKSCfzG7nYGZcJ=FG4OobSzRRPQ@mail.gmail.com>

On Sat, Jan 25, 2014 at 3:57 AM, spir <denis.spir at gmail.com> wrote:
> Note: AFAIK most financial software use integers for this reason and to
> avoid (or control) rounding errors.

I don't think this is true (no flame intended, hopefully you know I'm
forever in your debt Denis): there's a famous scam where insiders at a
major financial institution set the software so it always rounds down,
and the difference was deposited in their account. It was a matter of
fractions of pennies on a per-scam basis. I'm not certain if this ever
actually happened (I thought it did, but Snopes seems agnostic).

http://www.snopes.com/business/bank/salami.asp

-- 
Keith

From oscar.j.benjamin at gmail.com  Sat Jan 25 22:23:07 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Sat, 25 Jan 2014 21:23:07 +0000
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAO5ffbaAySvg1a3ALhWDMfjPVtJF+TiNYrV-E1t4Nb9L2u9Lfg@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 <CAO5ffbaAySvg1a3ALhWDMfjPVtJF+TiNYrV-E1t4Nb9L2u9Lfg@mail.gmail.com>
Message-ID: <CAHVvXxSF_PKOTeS4oAgbR6J2iXDU+2cqceLDyVsVhUFBkBNVFQ@mail.gmail.com>

On 25 January 2014 21:01, Keith Winston <keithwins at gmail.com> wrote:
>
> I think that you should probably do your math in floating point (why
> get complicated? And you might need the accuracy, for hundredths of
> dollars and interest) and then format the output to be what you want.
> Watch out for rounding.

It may not matter in this case but the key point about the Decimal
module is that it implements "decimal floating point" whereas ordinary
floats implement "binary floating point". I would prefer to use the
decimal module which can represent decimal values exactly and perform
simple decimal-type computations such as this one exactly.

Incidentally you can use the Decimal module to see how the *exact*
value of a float looks when written out in decimal digits:

>>> from decimal import Decimal as D
>>> D(0.5) # 0.5 can be represented exactly in binary FP
Decimal('0.5')
>>> D(0.1) # 0.1 cannot
Decimal('0.1000000000000000055511151231257827021181583404541015625')
>>> D(3.49)
Decimal('3.4900000000000002131628207280300557613372802734375')
>>> D(3.499)
Decimal('3.499000000000000110134124042815528810024261474609375')


Oscar

From alan.gauld at btinternet.com  Sat Jan 25 22:38:30 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 25 Jan 2014 21:38:30 +0000
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E412DF.5080603@gmail.com>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <52E412DF.5080603@gmail.com>
Message-ID: <lc1asa$2ml$1@ger.gmane.org>

On 25/01/14 19:39, bob gailer wrote:
> On 1/24/2014 10:28 PM, bob gailer wrote:
>
> Sorry for misspelling parens.
>
> My reason for requesting the various names is that it makes
> communication clear, explicit and terse.
>
> When someone says just "brackets" what does he actually mean?

In UK English speaking places 'brackets' by default means what
US English speakers call parentheses.

Whereas parentheses means any kind of parenthetical
expression which includes dashes, quotes and any kind of bracket
etc.

This was one of the biggest surprises when I first wrote a book
for a US publisher. One reviewer went so far as to suggest
that my level of "illiteracy" meant the book should be
rejected, because if I spelt parentheses as brackets how
could I possibly know anything about programming...

I actually intended pulling together a list of all the
Americanisms that I had to modify in my original text but
deadlines got in the way and I never got round to it.
But I was amazed at how many language changes were
necessary.

Language is a funny thing.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From keithwins at gmail.com  Sat Jan 25 22:38:59 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 25 Jan 2014 16:38:59 -0500
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAO5ffbYM2OzBZPdNYhW9bbVbKSCfzG7nYGZcJ=FG4OobSzRRPQ@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 <CAO5ffbYM2OzBZPdNYhW9bbVbKSCfzG7nYGZcJ=FG4OobSzRRPQ@mail.gmail.com>
Message-ID: <CAO5ffbZbWHY59DPGxvU8gzKK-yeenD3=xkzr0HKXhYN8aPi+7g@mail.gmail.com>

Also, just to be clear: I'd suggest floats because decimal requires
importing a module and using the non-built-in features thereof,
especially if you're going to do something like
decimal.getcontext().prec (even that doesn't set precision AFTER the
decimal point... only total precision). My point being that I don't
see the value of sending a beginner into that morass. I actually still
can't find how to force decimal to round to 3 places after the
decimal... (actually, I can't find a single reference to .prec except
in examples in the standard library doc of decimal
http://docs.python.org/3.3/library/decimal.html#decimal.getcontext)

And finally: when I said "watch out for rounding", I meant be prepared
for it. It is correct that rounding happens (otherwise the Snopes
Salami scam happens), and I can't imagine that at the level at which
the OP is working, any subtle control over rounding will be important
(i.e. ROUNDING_CEILING or any such thing).

Keith

From alan.gauld at btinternet.com  Sat Jan 25 22:47:14 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Sat, 25 Jan 2014 21:47:14 +0000
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAO5ffbYM2OzBZPdNYhW9bbVbKSCfzG7nYGZcJ=FG4OobSzRRPQ@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 <CAO5ffbYM2OzBZPdNYhW9bbVbKSCfzG7nYGZcJ=FG4OobSzRRPQ@mail.gmail.com>
Message-ID: <lc1bcl$7t8$1@ger.gmane.org>

On 25/01/14 21:19, Keith Winston wrote:
> On Sat, Jan 25, 2014 at 3:57 AM, spir <denis.spir at gmail.com> wrote:
>> Note: AFAIK most financial software use integers for this reason and to
>> avoid (or control) rounding errors.
>
> I don't think this is true

I can't speak for the general case but the only major financial app I've 
worked on (a mainframe billing system in COBOL) was done in pennies. It 
was a major rewrite of a legacy system  for the
"Millenium Bug". (It used the year 00 as a special case for
terminated accounts!! Amongst other foibles)...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From oscar.j.benjamin at gmail.com  Sat Jan 25 23:09:56 2014
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Sat, 25 Jan 2014 22:09:56 +0000
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAO5ffbZbWHY59DPGxvU8gzKK-yeenD3=xkzr0HKXhYN8aPi+7g@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 <CAO5ffbYM2OzBZPdNYhW9bbVbKSCfzG7nYGZcJ=FG4OobSzRRPQ@mail.gmail.com>
 <CAO5ffbZbWHY59DPGxvU8gzKK-yeenD3=xkzr0HKXhYN8aPi+7g@mail.gmail.com>
Message-ID: <CAHVvXxQGUHFZHKQDyTnnQVTmVibPoWN=0sdWpY5SucbnG8-mxg@mail.gmail.com>

On 25 January 2014 21:38, Keith Winston <keithwins at gmail.com> wrote:
>
> Also, just to be clear: I'd suggest floats because decimal requires
> importing a module and using the non-built-in features thereof,

Importing a module is not something to be afraid of. Python comes with
loads of modules especially so you can import them! :P

Also as of CPython 3.3 the decimal module is rewritten in C (which is
what is normally meant by "built-in").

> especially if you're going to do something like
> decimal.getcontext().prec (even that doesn't set precision AFTER the
> decimal point... only total precision). My point being that I don't
> see the value of sending a beginner into that morass.

Maybe it's tricky for a beginner. It is however good advice that you
should not use binary floating point for financial calculations.

> I actually still
> can't find how to force decimal to round to 3 places after the
> decimal...

I find myself using this:

>>> from decimal import Decimal as D
>>> D('0.1234567').quantize(D('1.000'))
Decimal('0.123')

Perhaps it would be better though to point at this:
>>> round(D('0.123456'), 3)
Decimal('0.123')

> (actually, I can't find a single reference to .prec except
> in examples in the standard library doc of decimal
> http://docs.python.org/3.3/library/decimal.html#decimal.getcontext)

.prec is "significant figures" rather than "decimal places" so it's
not what you want here.

> And finally: when I said "watch out for rounding", I meant be prepared
> for it. It is correct that rounding happens (otherwise the Snopes
> Salami scam happens), and I can't imagine that at the level at which
> the OP is working, any subtle control over rounding will be important
> (i.e. ROUNDING_CEILING or any such thing).

Some calculations need rounding in any fixed-width floating point
system. The decimal module let's you go up to 425 million digits
though:
>>> from decimal import MAX_PREC
>>> MAX_PREC
425000000

More importantly it has traps that you can use to catch any example of
inexact computation:

>>> from decimal import localcontext, Inexact
>>> with localcontext() as ctx:
...     ctx.traps[Inexact] = True
...     D(1) / 3
...
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
decimal.Inexact: [<class 'decimal.Inexact'>]

This way you can feel confident that your results are exact or else
you'd have seen an error message.


Oscar

From denis.spir at gmail.com  Sun Jan 26 01:12:56 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 26 Jan 2014 01:12:56 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAO5ffbaAySvg1a3ALhWDMfjPVtJF+TiNYrV-E1t4Nb9L2u9Lfg@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 <CAO5ffbaAySvg1a3ALhWDMfjPVtJF+TiNYrV-E1t4Nb9L2u9Lfg@mail.gmail.com>
Message-ID: <52E45308.50500@gmail.com>

On 01/25/2014 10:01 PM, Keith Winston wrote:
> On Sat, Jan 25, 2014 at 3:57 AM, spir <denis.spir at gmail.com> wrote:
>>> .009 to the price, so that people do not have to type the full amount.
>>>    Example, 3.49 /gallon would return 3.499 /gallon.
>>>
>>> This is what I have tried and the results of it.
>>>
>>> def gas_price(price):
>>>      price == raw_input("What is the price of gas?")  return price + .09
>>>     3.49=> 3.4899999999999998
>
> I think there's an inconsistency in your post that might confuse the
> answers. You mention in the lead that you want to add 9 ONE HUNDREDTHS
> of a dollar, or tenths of a cent (which is in fact how gas is priced
> in the US, and yes it's crazy stupid). However in your example you add
> only tenths, but then in the answer you appear to have added
> hundredths, which makes me think that you didn't cut & paste, but
> rather retyped (and mistyped).
>
> This will make it a little trickier to use Denis' last idea of using
> integers, since you'll have to take them out one more order of
> magnitude.

I guess this is what I wrote (unit was 1/10 cent), or maybe I misunderstand your 
point.

>  If this exercise is later followed by interest
> calculations, or anything like that, you might regret limiting your
> internal accuracy/representation.
>
> I think that you should probably do your math in floating point (why
> get complicated? And you might need the accuracy, for hundredths of
> dollars and interest) and then format the output to be what you want.
> Watch out for rounding.
>
>>>> p = 3.499
>>>> print('{0:.3f}'.format(p))   # format a float with 3 places after the decimal
> 3.499
>>>> p = 3.4994
>>>> print('{0:.3f}'.format(p))
> 3.499
>>>> p = 3.4999999
>>>> print('{0:.3f}'.format(p))
> 3.500

Yes; but this only corrects output, fo the user's comfort. If you need to do 
further computations, then the internal representation must also be right (else 
you'll get at best rounding errors, at worst worse ;-), and this can only be 
ensured by computing on integers or decimals. Typically, using integers, you'll 
choose a unit a few orders of magnitude lower than the most precise numbers 
possibly involved in computations (eg, a tax rate of 0.1234567 ;-).

d

From denis.spir at gmail.com  Sun Jan 26 01:19:58 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 26 Jan 2014 01:19:58 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAO5ffbYM2OzBZPdNYhW9bbVbKSCfzG7nYGZcJ=FG4OobSzRRPQ@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 <CAO5ffbYM2OzBZPdNYhW9bbVbKSCfzG7nYGZcJ=FG4OobSzRRPQ@mail.gmail.com>
Message-ID: <52E454AE.2050500@gmail.com>

On 01/25/2014 10:19 PM, Keith Winston wrote:
> On Sat, Jan 25, 2014 at 3:57 AM, spir <denis.spir at gmail.com> wrote:
>> Note: AFAIK most financial software use integers for this reason and to
>> avoid (or control) rounding errors.
>
> I don't think this is true (no flame intended, hopefully you know I'm
> forever in your debt Denis): there's a famous scam where insiders at a
> major financial institution set the software so it always rounds down,
> and the difference was deposited in their account. It was a matter of
> fractions of pennies on a per-scam basis. I'm not certain if this ever
> actually happened (I thought it did, but Snopes seems agnostic).
>
> http://www.snopes.com/business/bank/salami.asp

There's a similar story in France as well, but it was several decades ago. 
Incendentally, I used to know several people involved in financial software 
companies; they did use integers for all computations. Maybe today they use 
decimals, dunno (since then, decimal libs have become far more famous and used).

d

From denis.spir at gmail.com  Sun Jan 26 01:24:27 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 26 Jan 2014 01:24:27 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAO5ffbZbWHY59DPGxvU8gzKK-yeenD3=xkzr0HKXhYN8aPi+7g@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 <CAO5ffbYM2OzBZPdNYhW9bbVbKSCfzG7nYGZcJ=FG4OobSzRRPQ@mail.gmail.com>
 <CAO5ffbZbWHY59DPGxvU8gzKK-yeenD3=xkzr0HKXhYN8aPi+7g@mail.gmail.com>
Message-ID: <52E455BB.9040201@gmail.com>

On 01/25/2014 10:38 PM, Keith Winston wrote:
> Also, just to be clear: I'd suggest floats because decimal requires
> importing a module and using the non-built-in features thereof

The issue is not that much whether it's supported by builtins, in software, but 
by CPU's; which is not the case, so that all computations are made in 
software... there used to be some machines with builtin decimals (internal 
representation), maybe there still are some, but certainly not in mainstream 
computers.

d

From steve at pearwood.info  Sun Jan 26 02:12:32 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Jan 2014 12:12:32 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E371CC.4030102@gmail.com>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <20140125041440.GV3915@ando> <52E371CC.4030102@gmail.com>
Message-ID: <20140126011232.GX3915@ando>

On Sat, Jan 25, 2014 at 09:11:56AM +0100, spir wrote:

> As a foreigner, I noticed that english native speakers use both the series 
> round / square / curly / angle brackets, and individual terms parens (no 
> 'd' ;-) / brackets / braces / chevrons. No major issue, except for 
> 'brackets' which can be either a collective term or specific to [].

In the UK and Australia, "brackets" on its own refers to round brackets 
(parentheses), as they are the most common form. We never use "brackets" 
on its own to mean [], but only (), and the only time we bother to say 
"round brackets" is when there is a need to disambiguate them from 
square ones.


-- 
Steven

From steve at pearwood.info  Sun Jan 26 02:55:26 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 26 Jan 2014 12:55:26 +1100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <52E412DF.5080603@gmail.com>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <52E412DF.5080603@gmail.com>
Message-ID: <20140126015526.GY3915@ando>

On Sat, Jan 25, 2014 at 02:39:11PM -0500, bob gailer wrote:
> On 1/24/2014 10:28 PM, bob gailer wrote:
> 
> Sorry for misspelling parens.
> 
> My reason for requesting the various names is that it makes 
> communication clear, explicit and terse.
> 
> When someone says just "brackets" what does he actually mean?

It's possible to write ambiguous or unclear sentences about anything, 
not just brackets. Singling out them out for special treatment makes 
little sense to me. The nature of the English language is that we can 
write unclear sentences:

     "And then she told her that she knew that he said that she knew
     about that time he and she kissed at a party..."

How many people are involved? This is an extreme case, exaggerated for 
effect, but people do speak like that and given a little bit of context 
people are usually pretty good at disambiguation. Compared to that, 
inferring the required type of bracket is usually trivial.

If I'm talking to other Australians, I'll generally use "bracket" on its 
own to mean round () brackets, as that's the normal use here. In an 
international context, it will be either obvious from context, or 
generic and apply equally to any sort of bracket.

E.g. if I'm talking about a line of code that says 

    print(mylist.index(None)

and say "you're missing the closing bracket", is it really so confusing 
to infer that it's a closing ROUND bracket ) rather than a square 
bracket ] that is needed? Even a beginner should be able to work that 
out.

But I'm only human, and it is possible that at some point I'll make a 
mistake and write a confusing sentence where the meaning cannot be 
inferred, whether that's about brackets or something else doesn't 
matter. If you, or anyone else, catches me making a *specific* ambiguous 
statement that is unclear, regardless of whether it is due to the word 
"bracket" or not, then I welcome people asking me to clarify.

This is an international forum, and English an international language 
with many slight differences between variations and dialects. Even in 
American English alone, there are ambiguous terms. "Coke" could mean a 
beverage by the Coca-Cola company, a generic or rival cola beverage, a 
generic carbonated beverage of arbitrary flavour, an illegal drug, or a 
type of coal.

http://strangemaps.wordpress.com/2008/08/18/308-the-pop-vs-soda-map/

Somehow Americans cope with that. They can learn to cope with the many 
flavours of brackets as well :-)

> For more grins see 
> http://www.codinghorror.com/blog/2008/06/ascii-pronunciation-rules-for-programmers.html
> and http://www.theasciicode.com.ar/

Nice :-)



-- 
Steven

From breamoreboy at yahoo.co.uk  Sun Jan 26 03:41:19 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Sun, 26 Jan 2014 02:41:19 +0000
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140126015526.GY3915@ando>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <52E412DF.5080603@gmail.com> <20140126015526.GY3915@ando>
Message-ID: <lc1ske$9u5$1@ger.gmane.org>

On 26/01/2014 01:55, Steven D'Aprano wrote:
>
> This is an international forum, and English an international language
> with many slight differences between variations and dialects. Even in
> American English alone, there are ambiguous terms. "Coke" could mean a
> beverage by the Coca-Cola company, a generic or rival cola beverage, a
> generic carbonated beverage of arbitrary flavour, an illegal drug, or a
> type of coal.
>
> http://strangemaps.wordpress.com/2008/08/18/308-the-pop-vs-soda-map/
>
> Somehow Americans cope with that. They can learn to cope with the many
> flavours of brackets as well :-)
>

Still my favourite 
http://english.stackexchange.com/questions/16285/what-is-the-meaning-of-the-expression-we-can-table-this 
as it caused a row between UK and US commanders during WWII.

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

Mark Lawrence


From keithwins at gmail.com  Sun Jan 26 04:22:38 2014
From: keithwins at gmail.com (Keith Winston)
Date: Sat, 25 Jan 2014 22:22:38 -0500
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAHVvXxQGUHFZHKQDyTnnQVTmVibPoWN=0sdWpY5SucbnG8-mxg@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 <CAO5ffbYM2OzBZPdNYhW9bbVbKSCfzG7nYGZcJ=FG4OobSzRRPQ@mail.gmail.com>
 <CAO5ffbZbWHY59DPGxvU8gzKK-yeenD3=xkzr0HKXhYN8aPi+7g@mail.gmail.com>
 <CAHVvXxQGUHFZHKQDyTnnQVTmVibPoWN=0sdWpY5SucbnG8-mxg@mail.gmail.com>
Message-ID: <CAO5ffbZ+xgff5nRFxLCt4kcRHc_O2f+VEVPzxn=JdZqCCd01LA@mail.gmail.com>

On Sat, Jan 25, 2014 at 5:09 PM, Oscar Benjamin
<oscar.j.benjamin at gmail.com> wrote:
> Perhaps it would be better though to point at this:
>>>> round(D('0.123456'), 3)
> Decimal('0.123')

I think you are right. I didn't even think of round(). I think we have
confounded two issues in this thread, the internal
representation/accuracy, and the final presentation. They aren't
really the same thing, unless we force them to be (i.e. using ints).

-- 
Keith

From denis.spir at gmail.com  Sun Jan 26 08:49:19 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 26 Jan 2014 08:49:19 +0100
Subject: [Tutor] code works in windows command but not ubuntu terminal
In-Reply-To: <20140126011232.GX3915@ando>
References: <BLU176-W6049F5804B55C2ED35E1EE9A10@phx.gbl>
 <20140124094735.GQ3915@ando> <52E32F49.1030102@gmail.com>
 <20140125041440.GV3915@ando> <52E371CC.4030102@gmail.com>
 <20140126011232.GX3915@ando>
Message-ID: <52E4BDFF.5020100@gmail.com>

On 01/26/2014 02:12 AM, Steven D'Aprano wrote:
> On Sat, Jan 25, 2014 at 09:11:56AM +0100, spir wrote:
>
>> As a foreigner, I noticed that english native speakers use both the series
>> round / square / curly / angle brackets, and individual terms parens (no
>> 'd' ;-) / brackets / braces / chevrons. No major issue, except for
>> 'brackets' which can be either a collective term or specific to [].
>
> In the UK and Australia, "brackets" on its own refers to round brackets
> (parentheses), as they are the most common form. We never use "brackets"
> on its own to mean [], but only (), and the only time we bother to say
> "round brackets" is when there is a need to disambiguate them from
> square ones.

I learn english everyday ;-) thank you, Steven!

d


From denis.spir at gmail.com  Sun Jan 26 09:09:51 2014
From: denis.spir at gmail.com (spir)
Date: Sun, 26 Jan 2014 09:09:51 +0100
Subject: [Tutor] How to correct decimal addition.
In-Reply-To: <CAO5ffbZ+xgff5nRFxLCt4kcRHc_O2f+VEVPzxn=JdZqCCd01LA@mail.gmail.com>
References: <CAFP9wO973x7K3zn8VMM5ZvzpVG3GQPtoyooyumpspo6NMz5R3Q@mail.gmail.com>
 <52E379D6.2050003@gmail.com> <52E37C96.7040901@gmail.com>
 <CAO5ffbYM2OzBZPdNYhW9bbVbKSCfzG7nYGZcJ=FG4OobSzRRPQ@mail.gmail.com>
 <CAO5ffbZbWHY59DPGxvU8gzKK-yeenD3=xkzr0HKXhYN8aPi+7g@mail.gmail.com>
 <CAHVvXxQGUHFZHKQDyTnnQVTmVibPoWN=0sdWpY5SucbnG8-mxg@mail.gmail.com>
 <CAO5ffbZ+xgff5nRFxLCt4kcRHc_O2f+VEVPzxn=JdZqCCd01LA@mail.gmail.com>
Message-ID: <52E4C2CF.8080207@gmail.com>

On 01/26/2014 04:22 AM, Keith Winston wrote:
> On Sat, Jan 25, 2014 at 5:09 PM, Oscar Benjamin
> <oscar.j.benjamin at gmail.com> wrote:
>> Perhaps it would be better though to point at this:
>>>>> round(D('0.123456'), 3)
>> Decimal('0.123')
>
> I think you are right. I didn't even think of round(). I think we have
> confounded two issues in this thread, the internal
> representation/accuracy, and the final presentation. They aren't
> really the same thing, unless we force them to be (i.e. using ints).

Yes. Side-note below.

In programming, there is a general confusion between ideas, such as <the number 
-1.23> and their representations, like "-1.23" "minus one dot twenty three", 
"moins un virgule vingt-trois", "-1,23", or varipus possible strings of bits. 
There are outer written or spoken representations (numerals, for numbers) and 
internal representations in memory, which we could call "raw data". Raw data are 
meaningless (and type-less). Obviously, many truely believe there are data with 
meaning or type, that is ideas, *in* a machine; especially many speak and 
obviously think as if there were _numbers_ in a computer; as if a machine had a 
mind and thought... Numbers and other ideas are only in "heads" of psychical 
(mental) living things, as far as we know. there are no numbers, colors, texts, 
characters, weapons... in a machine ;-)

The internal representation is no less a representation and a pure convention. 3 
can be written
	vvvvvv^^
(with, say, bits 'on' and 'off')
it is a pure conventional representation (albeit simple & logical), and works 
because routines supposed to operate on numbers take this conventional 
representation for granted, both for operations and for input/output conversions 
to/from outer written representations.

In both internal and external representations there may be issues related to the 
base (eg in python we can also write hex or bin numbers). And a major issue, 
that will last as long as CPU's don't process decimal fractionals natively 
(so-to-say), is the clash between our expectations related to outer decimals and 
the inner processing in binary representation.

d

From ankitarora121 at gmail.com  Sun Jan 26 23:23:38 2014
From: ankitarora121 at gmail.com (Ankit Arora)
Date: Mon, 27 Jan 2014 03:53:38 +0530
Subject: [Tutor] Multi Layered Graphs
Message-ID: <CAETFwhOUbs0mp8v8p8j1VgNC0J09j4G9ZR8NBWFaLiBtAUga=A@mail.gmail.com>

I'm working on a project which involves network graphs. Is there a library
that can help me do this:

I want to create multi-layered graphs i.e. graphs which contain a set
number of vertices but multiple 'layers' of edges i.e. same set of vertices
representing two or more properties in the same data structure.

One rather hacky solution can be to form a complete graph in igraph and
deal with the layers as if they were igraph edge attributes, though when
dealing with tens of thousands of vertices on a complete graph it will be
inefficient.

Any clue if something proper exists? If not, any more intelligent solutions
using existing libraries such as igraph/networkx?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140127/50b787a2/attachment.html>

From steve at pearwood.info  Mon Jan 27 02:20:54 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 27 Jan 2014 12:20:54 +1100
Subject: [Tutor] Multi Layered Graphs
In-Reply-To: <CAETFwhOUbs0mp8v8p8j1VgNC0J09j4G9ZR8NBWFaLiBtAUga=A@mail.gmail.com>
References: <CAETFwhOUbs0mp8v8p8j1VgNC0J09j4G9ZR8NBWFaLiBtAUga=A@mail.gmail.com>
Message-ID: <20140127012053.GA3915@ando>

On Mon, Jan 27, 2014 at 03:53:38AM +0530, Ankit Arora wrote:
> I'm working on a project which involves network graphs. Is there a library
> that can help me do this:
> 
> I want to create multi-layered graphs i.e. graphs which contain a set
> number of vertices but multiple 'layers' of edges i.e. same set of vertices
> representing two or more properties in the same data structure.

This may be a bit advanced for the "tutor" list, which is more aimed at 
learning the syntax and standard library. If nobody responds with an 
answer here, you might like to try asking on comp.lang.python, also 
available by email python-list at python.org.

-- 
Steven


From denis.heidtmann at gmail.com  Mon Jan 27 07:16:25 2014
From: denis.heidtmann at gmail.com (Denis Heidtmann)
Date: Sun, 26 Jan 2014 22:16:25 -0800
Subject: [Tutor] When is = a copy and when is it an alias
Message-ID: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>

Running python 2.7 in linux

Below are two extremes.  Can I get some guidance on this?

Thanks,
-Denis H

>>> a=zeros((2,3),dtype=int)
>>> b=a
>>> a[:,0]=[1,2]
>>> a
array([[1, 0, 0],
       [2, 0, 0]])
>>> b
array([[1, 0, 0],
       [2, 0, 0]])
>>> a=2
>>> a
2
>>> b
array([[1, 0, 0],
       [2, 0, 0]])
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140126/03921470/attachment.html>

From marcusodouglas at hotmail.com  Mon Jan 27 04:44:56 2014
From: marcusodouglas at hotmail.com (marcus douglas)
Date: Sun, 26 Jan 2014 22:44:56 -0500
Subject: [Tutor] Python tutoring
Message-ID: <BLU172-W50D7DB7A85FDA81FA19ECDCA20@phx.gbl>

Hello, my name is Marcus Douglas and I'm a student at College of Central Florida, I'm contacting you because this is my first year programming and I'm seriously seeking some HELP...ASAP...ThanksMarcus Douglas 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140126/4475f906/attachment.html>

From steve at pearwood.info  Mon Jan 27 10:20:32 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 27 Jan 2014 20:20:32 +1100
Subject: [Tutor] Python tutoring
In-Reply-To: <BLU172-W50D7DB7A85FDA81FA19ECDCA20@phx.gbl>
References: <BLU172-W50D7DB7A85FDA81FA19ECDCA20@phx.gbl>
Message-ID: <20140127092032.GC3915@ando>

On Sun, Jan 26, 2014 at 10:44:56PM -0500, marcus douglas wrote:

> Hello, my name is Marcus Douglas and I'm a student at College of 
> Central Florida, I'm contacting you because this is my first year 
> programming and I'm seriously seeking some HELP...ASAP...

Hello Marcus, and welcome!

We hope that we can help you, but only if you ask us questions! What are 
you having trouble with? Please don't say "everything" :-)

Remember, we're not here to do your work for you, and your College 
almost certainly has rules about plagiarism and collaboration, so please 
try to ask generic questions about the language rather than specific 
questions about homework questions. If you must ask homework questions, 
expect that we'll only give you round-about answers that hint at a 
solution.

Good questions:

"What's a variable?"

"Can you explain exceptions? I don't understand them."

"I have a for-loop, and I want to exit it early. What should I do?"

"How do I look for an item in a list? I tried "find(my_list, item) but 
it printed NameError."

"What's the best way to read a file with items separated by tabs?"

"Here is my code. I tried running it, expecting this result, but got 
this different result instead. What did I do wrong?"


Bad questions:

"Help!?"

"Here's a project I have to do for my course. Solve it for me. 
Urgently. Because I forgot to do my project for the last three weeks 
and it's due tomorrow."

"Here's some code. It doesn't work. Fix it for me."

      

Good luck, and happy programming!



-- 
Steven

From steve at pearwood.info  Mon Jan 27 10:31:51 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 27 Jan 2014 20:31:51 +1100
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
Message-ID: <20140127093151.GD3915@ando>

Hi Denis, and welcome!

On Sun, Jan 26, 2014 at 10:16:25PM -0800, Denis Heidtmann wrote:

> Running python 2.7 in linux
> 
> Below are two extremes.  Can I get some guidance on this?

In Python, = is ALWAYS an alias, never a copy, unless you explicitly do 
something to make a copy. For example, with dicts, there is a `copy` 
method:

newdict = olddict.copy()

But it's not always *obvious* that you're just aliasing the same object. 
For example, this is obvious:

py> a = []
py> b = a  # b is now a new name for a
py> a.append(42)  # modifies the list in place
py> b
[42]

but this is not:

py> a = 23
py> b = a  # b is now a new name for a
py> a = a + 1
py> b
23


In this second case, b is unchanged because `a = a + 1` doesn't *modify* 
a, it makes a new value (23 + 1 => 24) and assigns that new value to a, 
leaving b unchanged.


In your example below, I take it you are using numpy. You should say so, 
in case it is unclear.

> >>> a=zeros((2,3),dtype=int)
> >>> b=a
> >>> a[:,0]=[1,2]
> >>> a
> array([[1, 0, 0],
>        [2, 0, 0]])
> >>> b
> array([[1, 0, 0],
>        [2, 0, 0]])

In this example, you bind the name "a" to an array of zeroes, then bind 
the name "b" to the same array. "Name binding" is another term for 
assignment in Python. So a and b are two names for the same array. When 
you modify the array via the name "a", b sees the same changes because 
they are the same array.

Even though the line

a[:,0] = [1, 2]

looks like an assignment, it's not actually a name binding, because 
you're only assigning to a slice of the array, not the name. That makes 
it an in-place modification, just like appending to a list.

But this code that follows:

> >>> a=2
> >>> a
> 2
> >>> b
> array([[1, 0, 0],
>        [2, 0, 0]])

is different. Here, the line `a = 2` is an actual name binding. It makes 
the name `a` refer to the value 2, instead of the array it used to refer 
to. But that doesn't change the array in any way, nor does it change 
`b`, so b is unaffected.


Hope this helps,


-- 
Steven

From denis.spir at gmail.com  Mon Jan 27 10:53:08 2014
From: denis.spir at gmail.com (spir)
Date: Mon, 27 Jan 2014 10:53:08 +0100
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
Message-ID: <52E62C84.4000308@gmail.com>

On 01/27/2014 07:16 AM, Denis Heidtmann wrote:
> Running python 2.7 in linux
>
> Below are two extremes.  Can I get some guidance on this?
>
> Thanks,
> -Denis H
>
>>>> a=zeros((2,3),dtype=int)
>>>> b=a
>>>> a[:,0]=[1,2]
>>>> a
> array([[1, 0, 0],
>         [2, 0, 0]])
>>>> b
> array([[1, 0, 0],
>         [2, 0, 0]])
>>>> a=2
>>>> a
> 2
>>>> b
> array([[1, 0, 0],
>         [2, 0, 0]])

Note: your example is strongly obscured by using weird and rare features that 
don't bring any helpful point to the actual problematic concepts you apparently 
want to deal with.

It seems you are confusing 2 issues: relation (reference) between values 
(objects) and relations between symbols (variables).

The last part of your example implies that you expect that, maybe, symbol 'b' 
may now magically point to 2 just because it were corelated with 'a', which was 
set to point to 2. Correct? If so, you are wrong: there is no relation between 
symbols in python (nore in any other language I know, for the matter). Symbols 
'a' and 'b' are independant, whatever the possible relations between their 
values. If you *replace* a's value, this has no effect on b, even if they 
previously held the very same, unique, value.

Python 3.3.2+ (default, Oct  9 2013, 14:50:09)
[GCC 4.8.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [1,2,3]
>>> b = a
>>> a is b
True
>>> a = (1,2)	# replacement
>>> b
[1, 2, 3]

Now, there are 2 ways to change a symbol's value: to *replace* it globally as 
above, or to *modify* it partly

>>> a = [1,2,3]
>>> b = a
>>> a is b
True
>>> a[1] = 0	# modification
>>> a
[1, 0, 3]
>>> b
[1, 0, 3]
>>> a is b
True

A misleading point is exemplified by "a is b": it does not mean that both 
symbols actually are the same one (unique), but that _their value objects_ are 
the same one (unique). This is the role of symbols: once defined, they are used 
for whatever they represent. Here symbols a & b just play their normal role of 
symbols, right?

The above example of modification is only possible if the value is complex (and 
mutable). Simple values like numbers or strings obviously cannot be modified, 
only replaced. Thus, such simple values just behave like "plain old values" in 
static or historical languages (in which there aren't symbols & values are 
runtime, instead plain adresses & raw data). In such languages there is 
systematic copy on assignment, unless one explicitely uses pointers. Maybe you 
are used to that, and expect such behaviour in python.

Quite the opposite, in python "symbolic assignment" (where the right side also 
is a symbol) never copies, in fact never creates a new value, but bind the left 
symbol to the same, unique value, as the right symbol.

Note: such are the semantics (the meaning) of the language. But since as said 
above this does not make any difference in practice for simple values, the 
language implementation is in fact free to copy under the hood, if this is 
simpler or more efficient to do so: the language's semantics are preserved 
nevertheless. However, python's standard implementation does not appear to do so:

>>> a = -12.345
>>> b = a
>>> a is b
True		# a & b are bound to the same value, there's only one -12.345

d






From __peter__ at web.de  Mon Jan 27 10:54:15 2014
From: __peter__ at web.de (Peter Otten)
Date: Mon, 27 Jan 2014 10:54:15 +0100
Subject: [Tutor] When is = a copy and when is it an alias
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
Message-ID: <lc5abn$9tt$1@ger.gmane.org>

Denis Heidtmann wrote:

> Running python 2.7 in linux
> 
> Below are two extremes.  Can I get some guidance on this?

>>>> a=zeros((2,3),dtype=int)
>>>> b=a
>>>> a[:,0]=[1,2]
>>>> a
> array([[1, 0, 0],
>        [2, 0, 0]])
>>>> b
> array([[1, 0, 0],
>        [2, 0, 0]])
>>>> a=2
>>>> a
> 2
>>>> b
> array([[1, 0, 0],
>        [2, 0, 0]])

In short:

x = ...

binds a name, it never copies. On the other side

x[whatever] = ...
or
x.attr = ...

can run arbitrary code that may or may not alter the object bound to x 
inplace. You have to know the type of x to know what happens.


From denis.spir at gmail.com  Mon Jan 27 11:10:54 2014
From: denis.spir at gmail.com (spir)
Date: Mon, 27 Jan 2014 11:10:54 +0100
Subject: [Tutor] Multi Layered Graphs
In-Reply-To: <CAETFwhOUbs0mp8v8p8j1VgNC0J09j4G9ZR8NBWFaLiBtAUga=A@mail.gmail.com>
References: <CAETFwhOUbs0mp8v8p8j1VgNC0J09j4G9ZR8NBWFaLiBtAUga=A@mail.gmail.com>
Message-ID: <52E630AE.7050201@gmail.com>

On 01/26/2014 11:23 PM, Ankit Arora wrote:
> I'm working on a project which involves network graphs. Is there a library
> that can help me do this:
>
> I want to create multi-layered graphs i.e. graphs which contain a set
> number of vertices but multiple 'layers' of edges i.e. same set of vertices
> representing two or more properties in the same data structure.
>
> One rather hacky solution can be to form a complete graph in igraph and
> deal with the layers as if they were igraph edge attributes, though when
> dealing with tens of thousands of vertices on a complete graph it will be
> inefficient.
>
> Any clue if something proper exists? If not, any more intelligent solutions
> using existing libraries such as igraph/networkx?

Just a personal point of view: I usually end up implementing custom graphs or 
trees because it is rather simple [*] and because of the variety of structures 
and features. (Maybe that's why there are no general purpose node/tree/graph 
libs, only highly specialised one, as for XML parsing.)

If you take this route and need help or advice on given points or features, we 
can probably be of some use.

Denis

[*] compared the overall app: if a graph is complex, then the app it is a 
component of is even more complex

From breamoreboy at yahoo.co.uk  Mon Jan 27 15:07:46 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Mon, 27 Jan 2014 14:07:46 +0000
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <52E62C84.4000308@gmail.com>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
Message-ID: <lc5p76$tun$1@ger.gmane.org>

On 27/01/2014 09:53, spir wrote:
> On 01/27/2014 07:16 AM, Denis Heidtmann wrote:
>> Running python 2.7 in linux
>>
>> Below are two extremes.  Can I get some guidance on this?
>>
>> Thanks,
>> -Denis H
>>
>>>>> a=zeros((2,3),dtype=int)
>>>>> b=a
>>>>> a[:,0]=[1,2]
>>>>> a
>> array([[1, 0, 0],
>>         [2, 0, 0]])
>>>>> b
>> array([[1, 0, 0],
>>         [2, 0, 0]])
>>>>> a=2
>>>>> a
>> 2
>>>>> b
>> array([[1, 0, 0],
>>         [2, 0, 0]])
>
> Note: your example is strongly obscured by using weird and rare features
> that don't bring any helpful point to the actual problematic concepts
> you apparently want to deal with.
>

Nothing weird and rare about it, just something from the numpy maths 
library and not pure Python.

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

Mark Lawrence


From denis.heidtmann at gmail.com  Mon Jan 27 18:04:17 2014
From: denis.heidtmann at gmail.com (Denis Heidtmann)
Date: Mon, 27 Jan 2014 09:04:17 -0800
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <52E62C84.4000308@gmail.com>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
Message-ID: <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>

Thanks for the responses.

The distinction between replacement and modification seems to capture the
essential aspect and helps to clarify the issue for me.

spir:
Quite the opposite, in python "symbolic assignment" (where the right side
also is a symbol) never copies, in fact never creates a new value, but bind
the left symbol to the same, unique value, as the right symbol.

If this is accurate, I can see crazy bugs in my future until I internalize
it.

Python 2.7.3 (default, Sep 26 2013, 20:03:06)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=[2,3]
>>> b=[10,20]
>>> a[0]=b[0]
>>> a
[10, 3]
>>> b[0]=100
>>> a
[10, 3]

Apparently a[0]=b[0] does not qualify as "symbolic assignment" in this
case. a[0] is not a reference to b[0].  I think I see the essential
distinction.  Experience will complete the picture for me.

-DH
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140127/82155a58/attachment.html>

From fomcl at yahoo.com  Mon Jan 27 19:46:14 2014
From: fomcl at yahoo.com (Albert-Jan Roskam)
Date: Mon, 27 Jan 2014 10:46:14 -0800 (PST)
Subject: [Tutor] Multi Layered Graphs
Message-ID: <1390848374.33277.BPMail_high_noncarrier@web163801.mail.gq1.yahoo.com>


------------------------------
On Sun, Jan 26, 2014 11:23 PM CET Ankit Arora wrote:

>I'm working on a project which involves network graphs. Is there a library
>that can help me do this:
>
>I want to create multi-layered graphs i.e. graphs which contain a set
>number of vertices but multiple 'layers' of edges i.e. same set of vertices
>representing two or more properties in the same data structure.
>
>One rather hacky solution can be to form a complete graph in igraph and
>deal with the layers as if they were igraph edge attributes, though when
>dealing with tens of thousands of vertices on a complete graph it will be
>inefficient.
>
>Any clue if something proper exists? If not, any more intelligent solutions
>using existing libraries such as igraph/networkx?

Maybe D3py, a Python wrapper for D3.js. No experience with it but it looks great.

From dyoo at hashcollision.org  Mon Jan 27 20:01:56 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Mon, 27 Jan 2014 11:01:56 -0800
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
 <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
Message-ID: <CAGZAPF4M1=XGYTXTu9gkJiA2R5hG0q9xvMi64VH22JE0RjNtgw@mail.gmail.com>

> Apparently a[0]=b[0] does not qualify as "symbolic assignment" in this case.
> a[0] is not a reference to b[0].  I think I see the essential distinction.
> Experience will complete the picture for me.

Yes.  The distinction is something that is blurred by Python's syntax.
 The "=" is a conceptually different thing, based on what's on the
"left hand side" of the "=".  It can means "variable binding" or
"structure mutation", and those concepts are similar, but not the same
thing.   And variable binding itself can even have a slightly
different meaning, depending on whether the surrounding context is a
function definition or not, establishing a local or global variable
binding.  Whew!

Assignment can be tricky.  It's at the heart of one of the things that
makes programming "hard": it is very much about change, about
dynamics, about having to reason what the world looks like "before"
and "after" a change.

(And hence why some customized programming languages for beginners
outright prohibit the assignment operator.)

From eryksun at gmail.com  Mon Jan 27 22:00:15 2014
From: eryksun at gmail.com (eryksun)
Date: Mon, 27 Jan 2014 16:00:15 -0500
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <CAGZAPF4M1=XGYTXTu9gkJiA2R5hG0q9xvMi64VH22JE0RjNtgw@mail.gmail.com>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
 <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
 <CAGZAPF4M1=XGYTXTu9gkJiA2R5hG0q9xvMi64VH22JE0RjNtgw@mail.gmail.com>
Message-ID: <CACL+1as5VJKUDTaR7pHBHa-y5pw=86MFX_DA+T1-9fo-xHAAHw@mail.gmail.com>

On Mon, Jan 27, 2014 at 2:01 PM, Danny Yoo <dyoo at hashcollision.org> wrote:
> And variable binding itself can even have a slightly
> different meaning, depending on whether the surrounding context is a
> function definition or not, establishing a local or global variable
> binding.  Whew!

Name binding is local unless you tell Python otherwise by declaring a
name to be global (also nonlocal in 3.x). CPython, for example,
compiles top-level module code to use the STORE_NAME instruction,
which stores to the locals mapping of the current frame. If the name
is declared global, it instead uses STORE_GLOBAL.

Module-level code is flagged to create a frame for which locals and
globals are the same dict. You could, however, exec code using
separate dicts for locals and globals:

    src = r'''
    global x
    x = 0
    y = 1
    '''

    gvars, lvars = {}, {}
    exec src in gvars, lvars

    ####

    >>> sorted(gvars)
    ['__builtins__', 'x']

    >>> sorted(lvars)
    ['y']

CPython bytecode:

    >>> code = compile(src, '<str>', 'exec')
    >>> dis.dis(code)
      3           0 LOAD_CONST               0 (0)
                  3 STORE_GLOBAL             0 (x)

      4           6 LOAD_CONST               1 (1)
                  9 STORE_NAME               1 (y)
                 12 LOAD_CONST               2 (None)
                 15 RETURN_VALUE

From eryksun at gmail.com  Mon Jan 27 22:17:56 2014
From: eryksun at gmail.com (eryksun)
Date: Mon, 27 Jan 2014 16:17:56 -0500
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <lc5p76$tun$1@ger.gmane.org>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com> <lc5p76$tun$1@ger.gmane.org>
Message-ID: <CACL+1atpRkoJ7bS+Te_hPUuCqkpke81qFbq2rEPZW5vfGJ5B8g@mail.gmail.com>

On Mon, Jan 27, 2014 at 9:07 AM, Mark Lawrence <breamoreboy at yahoo.co.uk> wrote:
> On 27/01/2014 09:53, spir wrote:
>>
>> Note: your example is strongly obscured by using weird and rare features
>> that don't bring any helpful point to the actual problematic concepts
>> you apparently want to deal with.
>>
>
> Nothing weird and rare about it, just something from the numpy maths library
> and not pure Python.

NumPy arrays may seem weird to someone who expects a slice to create a
shallow copy of the data, in the way that slicing a `list` creates a
shallow copy:

    >>> a = [0, 2, 4]
    >>> b = a[:]

`b` is a copy of list `a`, so modifying `b` has no effect on `a`:

    >>> b[:] = [1, 3, 5]
    >>> a
    [0, 2, 4]

Slicing a NumPy array returns a new view on the data:

    a = np.array([0, 2, 4], dtype=object)
    b = a[:]

    >>> b.base is a
    True
    >>> b.flags.owndata
    False

The view shares the underlying data array, so modifying it also
changes the original:

    >>> b[:] = [1, 3, 5]
    >>> a
    array([1, 3, 5], dtype=object)

You have to ask for a `copy`:

    a = np.array([0, 2, 4], dtype=object)
    b = a.copy()

    >>> b.base is None
    True
    >>> b.flags.owndata
    True

    >>> b[:] = [1, 3, 5]
    >>> a
    array([0, 2, 4], dtype=object)

From denis.spir at gmail.com  Tue Jan 28 09:28:29 2014
From: denis.spir at gmail.com (spir)
Date: Tue, 28 Jan 2014 09:28:29 +0100
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
 <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
Message-ID: <52E76A2D.8090408@gmail.com>

On 01/27/2014 06:04 PM, Denis Heidtmann wrote:
> Apparently a[0]=b[0] does not qualify as "symbolic assignment" in this
> case. a[0] is not a reference to b[0].  I think I see the essential
> distinction.  Experience will complete the picture for me.

"symolic assignment" is my term, so whatever I mean with it qualifies as 
symbolic assignment ;-); and tes, your example a[0]=b[0] is indeed a symbolic 
assignment (because the right side "b[0]" denotes a value, an object, and could 
be on the left side of an assignment)
the distinction between "replacement" & "modification" also uses my terms; 
better you know that because if you talk with programmers using these terms as 
key words, others will be surprised

The real point is: maybe read again my previous post. I insisted on the fact 
that in python _symbols_ are not corelated, never ever. Your remark here seems 
to show that you expect a[0] and b[0] to be corelated, in such a way that if we 
change one of them the second should follow. No. Values are made unique by 
symbolic assignment; but this can only show if you modify them partly (not 
replace globally), thus can only show if those are complex values.

>>> a = [1, [1,2]]
>>> b = a
>>> b
[1, [1, 2]]
>>> b is a
True

a's and b's values are a single, unique object... as long as I only modifie them 
(the values) partly:

>>> a = [1,[2,3]]
>>> a[0] = 0
>>> b
[0, [1, 2]]
>>> a[1] = [0,0]
>>> b
[0, [0, 0]]
>>> a is b
True

>>> a[0] = b[0]
>>> a[0] is b[0]
True

Here i make their first elements the same unique value. But I'm blocked to show 
it (other than using 'is') because I cannot modify such objects (they are simple 
numbers). Since it is the _values_ which are related, not the symbols, if I 
replace one of them I break the relation.

>>> a[0] = 9
>>> a
[9, [2, 3]]
>>> b
[1, [0, 0]]

Right? On the other, if I create a relatoin between their second elements, then 
I can have something more interesting:

>>> a[1] = b[1]
>>> a[1] is b[1]
True
>>> a, b
([9, [0, 0]], [1, [0, 0]])
>>> a[1][1] = 9
>>> b[1][1]
9
>>> a, b
([9, [0, 9]], [1, [0, 9]])

You will get used to it... Also, it just works most of the time, except for 
corner cases where you will be trapped 2-3 times until you get it. (The reason 
is that unconsciously, when we want several symbols to have their proper values, 
we just do it right by assigning them apart, even if they (initially) have the 
same values. When instead we want a symbol to refer to the same value as 
another, we correctly use a symbolic assignment; instead of incorrectly 
assigning an equal, but distinct, value.]

denis

From duxbuz at hotmail.com  Tue Jan 28 10:48:30 2014
From: duxbuz at hotmail.com (Ian D)
Date: Tue, 28 Jan 2014 09:48:30 +0000
Subject: [Tutor] Coordinates TK and Turtle
Message-ID: <DUB123-W1450529722E1DCA637AC1CCBAD0@phx.gbl>

Hello 

I have some weird results when I run my code which is meant to display a canvas and a turtle and some text with the turtles coordinates. 

Basically the turtle coordinates do not seem to correspond with the TK create_text coordinates. 


t1.goto(100,100) 

canvas_id = cv1.create_text(t1.xcor(), t1.ycor(), font=("Purisa",12),anchor="nw") 

cv1.insert(canvas_id, 0, t1.pos()) 

I end up with this output: 
http://i1025.photobucket.com/albums/y319/duxbuz/coord-issues_zps1fca6d2b.jpg 

Could anyone help please? 

Thanks  		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140128/e612afe5/attachment.html>

From eryksun at gmail.com  Tue Jan 28 15:17:59 2014
From: eryksun at gmail.com (eryksun)
Date: Tue, 28 Jan 2014 09:17:59 -0500
Subject: [Tutor] Coordinates TK and Turtle
In-Reply-To: <DUB123-W1450529722E1DCA637AC1CCBAD0@phx.gbl>
References: <DUB123-W1450529722E1DCA637AC1CCBAD0@phx.gbl>
Message-ID: <CACL+1aufOS6SCMoe85GjqOEFvsGkKHSxym4=-E_oubmcAOrCAQ@mail.gmail.com>

On Tue, Jan 28, 2014 at 4:48 AM, Ian D <duxbuz at hotmail.com> wrote:
>
> I have some weird results when I run my code which is meant to display a
> canvas and a turtle and some text with the turtles coordinates.
>
> Basically the turtle coordinates do not seem to correspond with the TK
> create_text coordinates.
>
> t1.goto(100,100)
>
> canvas_id = cv1.create_text(t1.xcor(), t1.ycor(),
> font=("Purisa",12),anchor="nw")
>
> cv1.insert(canvas_id, 0, t1.pos())

A turtle has a `write` method:

http://docs.python.org/2/library/turtle#turtle.write

It sets up for undoing the operation, and then it has the screen write
on the Tk canvas. Here's the screen's `_write` method:

    >>> print inspect.getsource(turtle.TurtleScreen._write)
        def _write(self, pos, txt, align, font, pencolor):
            """Write txt at pos in canvas with specified font
            and color.
            Return text item and x-coord of right bottom corner
            of text's bounding box."""
            x, y = pos
            x = x * self.xscale
            y = y * self.yscale
            anchor = {"left":"sw", "center":"s", "right":"se" }
            item = self.cv.create_text(x-1, -y, text = txt,
                                       anchor = anchor[align],
                                       fill = pencolor, font = font)
            x0, y0, x1, y1 = self.cv.bbox(item)
            self.cv.update()
            return item, x1-1

xscale and yscale should be 1.0, but maybe not if you've called
`setworldcoordinates`. The y coordinate has to be negated, since it
increases from top to bottom in the canvas. I don't know about the -1
offset for the x coordinate. Scanning over the source, I don't see a
similar offset used for drawing lines, polygons, and images. So I
guess it's something to do with how `create_text` works. But I'm far
from being an expert with Tk widgets.

From mylesbroomes at hotmail.co.uk  Tue Jan 28 20:13:12 2014
From: mylesbroomes at hotmail.co.uk (myles broomes)
Date: Tue, 28 Jan 2014 19:13:12 +0000
Subject: [Tutor] Importing Pygame
Message-ID: <DUB111-W9162F91EAA4A9FD227CE4097AD0@phx.gbl>

I am trying to import pygame but everytime I do, I get an ImportError. Here is the code I'm trying to run:

import pygame,sys
from pygame.locals import *

pygame.init()
DISPLAYSURF=pygame.display.set_mode((400,300))
pygame.display.set_caption('Hello World!')
while True: #main game loop
    for event in pygame.event.get():
        if event.type==QUIT:
            pygame.quit()
            sys.exit()
    pygame.display.update()

And the error I get:

Traceback (most recent call last):
  File "C:\Python32\blankgame.py", line 1, in <module>
    import pygame,sys
ImportError: No module named 'pygame'

When I import pygame using the shell however, it works fine. I am using Python 3.2.3 and the Pygame installer I downloaded is pygame-1.9.2a0.win32-py3.2.msi. 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140128/45c824c5/attachment.html>

From davea at davea.name  Tue Jan 28 22:15:11 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 16:15:11 -0500 (EST)
Subject: [Tutor] Importing Pygame
References: <DUB111-W9162F91EAA4A9FD227CE4097AD0@phx.gbl>
Message-ID: <lc96fk$p4g$1@ger.gmane.org>

 myles broomes <mylesbroomes at hotmail.co.uk> Wrote in message:
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 

I'm guessing you're attempting to post here in this text newsgroup
 using html. Please use text. It's a pain to quote your message
 when none of it shows.

> And the error I get:

Traceback (most recent call last):
?? File "C:\Python32\blankgame.py", line 1, in <module>
?????? import pygame,sys
ImportError: No module named 'pygame'

When I import pygame using the shell however, it works fine. I am
 using Python 3.2.3 and the Pygame installer I downloaded is
 pygame-1.9.2a0.win32-py3.2.msi.


Please be as specific as possible.  Apparently you're running
 Windows and when you run your Python script from a cmd shell, the
 import works fine, but when you run it some other unspecified
 way, you get the import error.  You could learn a lot by printing
 sys.path, the search path for import.

My guess is that you have two different installs of python, and
 some difference in how you're launching the script is invoking
 the different installations.

While you're investigating,  please move your blankgame script
 somewhere that's NOT in the installation directory.  You'll only
 confuse things when some things happen to sortof
 work.



-- 
DaveA


From denis.heidtmann at gmail.com  Tue Jan 28 20:00:49 2014
From: denis.heidtmann at gmail.com (Denis Heidtmann)
Date: Tue, 28 Jan 2014 11:00:49 -0800
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <52E76A2D.8090408@gmail.com>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
 <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
 <52E76A2D.8090408@gmail.com>
Message-ID: <CAArUT0iCQ1gFFqbdmiLtw0JoqPgu3SWQL7vWj3DQakEs16PX=w@mail.gmail.com>

On Tue, Jan 28, 2014 at 12:28 AM, spir <denis.spir at gmail.com> wrote:

> <snip>
>
>  a = [1, [1,2]]
>>>> b = a
>>>> b
>>>>
>>> [1, [1, 2]]
>
>> b is a
>>>>
>>> True
>
> a's and b's values are a single, unique object... as long as I only
> modified them (the values) partly:
>
>  a = [1,[2,3]]
>>>> a[0] = 0
>>>> b
>>>>
>>> [0, [1, 2]]                  # this is where I get lost.
>
>> a[1] = [0,0]
>>>> b
>>>>
>>> [0, [0, 0]]
>
>> a is b
>>>>
>>> True
>
>  a[0] = b[0]
>>>> a[0] is b[0]
>>>>
>>> True
> <snip>
>
> denis



My python gets a different result:

 >>> a=[1,[1,2]]
>>> b=a
>>> b
[1, [1, 2]]
>>> a=[1,[2,3]]  # this breaks the connection.
>>> a[0]=0
>>> b
[1, [1, 2]]
>>> a[1]=[0,0]
>>> b
[1, [1, 2]]
>>>

What is going on?  I am more confused than I was a week ago.

-Denis H
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140128/8ed5f221/attachment.html>

From aubri at sandlininc.com  Tue Jan 28 20:38:20 2014
From: aubri at sandlininc.com (Aubri Sandlin)
Date: Tue, 28 Jan 2014 11:38:20 -0800
Subject: [Tutor] Installing Python on osx 10.9.1
Message-ID: <0F842DEE-0040-4F69-880C-9308E880626F@sandlininc.com>

I have installed Python.  When I open IDLE I get this warning:  >>> WARNING: The version of Tcl/Tk (8.5.9) in use may be unstable.
Visit http://www.python.org/download/mac/tcltk/ for current information.


I have downloaded and installed the latest version of TCL/TK and rebooted my computer.  I still get the above warning.  

What else do I need to do in order to be able to use Python?



From glester at avant.ca  Tue Jan 28 21:47:44 2014
From: glester at avant.ca (Glenn Lester)
Date: Tue, 28 Jan 2014 14:47:44 -0600
Subject: [Tutor] Importing Pygame
In-Reply-To: <DUB111-W9162F91EAA4A9FD227CE4097AD0@phx.gbl>
References: <DUB111-W9162F91EAA4A9FD227CE4097AD0@phx.gbl>
Message-ID: <CAAJkYqeLkPtLUQwWrLuJ58ogDJ9LRZ5otaFg=Hhx1B+6rav-OA@mail.gmail.com>

I think you typed a comma instead of a period when you coded import
pygame.sys
Or it may be my display. Check it out.

Best of Luck


On Tue, Jan 28, 2014 at 1:13 PM, myles broomes
<mylesbroomes at hotmail.co.uk>wrote:

> I am trying to import pygame but everytime I do, I get an ImportError.
> Here is the code I'm trying to run:
>
> import pygame,sys
> from pygame.locals import *
>
> pygame.init()
> DISPLAYSURF=pygame.display.set_mode((400,300))
> pygame.display.set_caption('Hello World!')
> while True: #main game loop
>     for event in pygame.event.get():
>         if event.type==QUIT:
>             pygame.quit()
>             sys.exit()
>     pygame.display.update()
>
> And the error I get:
>
> Traceback (most recent call last):
>   File "C:\Python32\blankgame.py", line 1, in <module>
>     import pygame,sys
> ImportError: No module named 'pygame'
>
> When I import pygame using the shell however, it works fine. I am using
> Python 3.2.3 and the Pygame installer I downloaded ispygame-1.9.2a0.win32-py3.2.msi.
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>


-- 

*Glenn Lester*

Software Tester

*Avant Systems Group*

*voice: *204.789.9596 x19 *|** fax: *204.789.9598 *|** email: *
glester at avant.ca*|** web: *www.avant.ca



*Quality People Delivering Quality Solutions*

CONFIDENTIALITY NOTICE: This correspondence and any attachment(s) may
contain confidential information that is legally privileged. If you are not
the intended recipient, or the person responsible for delivering it, you
are hereby notified that any disclosure, copying, distribution or use of
any of the aforementioned information is STRICTLY PROHIBITED. If you have
received this transmission in error, please permanently delete the original
transmission and its attachments without reading or saving in any manner.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140128/b92e42a7/attachment-0001.html>

From leamhall at gmail.com  Tue Jan 28 20:52:44 2014
From: leamhall at gmail.com (leam hall)
Date: Tue, 28 Jan 2014 14:52:44 -0500
Subject: [Tutor] subprocess.Popen help
Message-ID: <CACv9p5oySOtgro3Us0QLtbwmoNF6pFXbBso794jaK9TTi95yYA@mail.gmail.com>

Python tutorial for 2.6 (using 2.4 -- don't ask), first code blurb under 17.1.1

http://docs.python.org/2.6/library/subprocess.html?highlight=subprocess#subprocess.Popen

How would you make an ssh to another box put data back in "p"? The
goal is to run a shell command on a remote box and work with the
output on the local host.

Thanks!

Leam

-- 
Mind on a Mission

From Michael.Pierre at ccpoa.org  Tue Jan 28 23:46:38 2014
From: Michael.Pierre at ccpoa.org (Michael L. Pierre)
Date: Tue, 28 Jan 2014 22:46:38 +0000
Subject: [Tutor] If, elif, else
Message-ID: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>

I am a newbie with Python (programming in general) and I am trying to create a program that will take user name and dob and pump out their age, while on a person's birthday the output not only states their name and age, but also prints out ***HAPPY BIRTHDAY***
I have gotten it resolved to the point that it understands leap  years and gives the correct age. My problem arises when a date is input that is the current month, but a future date (i.e. today's date is 1/28/2014 but the input dob is 1/30/1967) It skips over the elif option to subtract one year and prints out ***HAPPY BIRTHDAY***
I am only going to paste the non-leap year code, because the leap year code is basically identical.

#Leapyear calculations/decision
if leap_year != int:
    age_month = int(current_split[1]) - int(dob_split[1])
    #print age_month
    if age_month != 0:
        month_less = 1
        age = int(current_split[0]) - int(dob_split[0]) - month_less
        print "you are", age, "years old"
    elif age_month == 0 and int(current_split[2]) > int(dob_split[2]):
        age = int(current_split[0]) - int(dob_split[0]) - month_less
        print "you are", age, "years old"
    else:
       age = int(current_split[0]) - int(dob_split[0])
       print "You are", age, "and today is your birthday ***HAPPY BIRTHDAY***"

Any help would be greatly appreciated :)

Michael Pierre
CCPOA IT Specialist
916-372-6060 Ext. 221


______________________________________________________________________
California Correctional Peace Officers Association Notice of Confidentiality:
This email message, including any attachments, is for the sole use of
the intended recipient(s). These items may contain confidential and/or
privileged information. Any unauthorized review, use, disclosure or
distribution is prohibited. If you are not the intended recipient,
please contact the sender by reply email and destroy all copies of
the original message.
______________________________________________________________________
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140128/5a9d13d3/attachment.html>

From stopitscurvy at gmail.com  Tue Jan 28 21:45:01 2014
From: stopitscurvy at gmail.com (scurvy scott)
Date: Tue, 28 Jan 2014 15:45:01 -0500
Subject: [Tutor] Can't figure out why I'm getting no output??
Message-ID: <CA+KU-OEY=eQvocZs-xSWvT=BSGYxgpe8besiQAkH4xpUvWkJUQ@mail.gmail.com>

Hey all.. First of all here is my code:

import requests
from bs4 import BeautifulSoup as beautiful


payload = {'username': 'XXXXX', 'password': 'XXXXXX'}
r = requests.post("http://dogehouse.org/index.php?page=login", data=payload)
soup = beautiful(r.text)
confirmed = str(soup.findAll('span',{'class':'confirmed'}))


print "Confirmed account balance" +confirmed[86:98]

I'm running it on Crunchbang/Debian Linux

I'm trying to write a basic scraper that I can use to output my current
account balance from my mining pool in my terminal.
I've tested the code in the regular python interpreter and it all executes
the way it should. But when I attempt to run it using "python whatever.py"
it doesn't give me any output. Any tips would be appreciated. Thanks.

scott
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140128/028c39b8/attachment.html>

From davea at davea.name  Wed Jan 29 01:42:25 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 19:42:25 -0500 (EST)
Subject: [Tutor] If, elif, else
References: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
Message-ID: <lc9ik7$8ne$1@ger.gmane.org>

 "Michael L. Pierre" <Michael.Pierre at ccpoa.org> Wrote in message:
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 

Start by posting in text form, since this is a text group.  You
 apparently posted in html. And you doublespaced.
 

Any reason you didn't use the date module?  The code would have
 been much simpler. 

> gotten it resolved to the point that it understands leap?? years and gives the correct age. 

Sometimes. 

> My problem arises when a date is input that is the current month, but a future date (i.e. today???s date is 1/28/2014 but the input dob is 1/30/1967)
 It skips over the elif option to subtract one year and prints out
 ***HAPPY BIRTHDAY***

> am only going to paste the non-leap year code, because the leap year code is basically identical.

??Problems from a quick perusal.  

 The first if clause tries to handle the cases where the month is
 different.  But it should only be subtracting 1 if age_month is
 negative. 

Next the elif clause. You subtract month_less but don't initialize
 it to zero.  Why bother subtracting anyway? In this clause
 there's no adjustment needed.

Next the missing elif for int(current_split[2])  < int(dob_split[2]):


-- 
DaveA


From davea at davea.name  Wed Jan 29 01:46:40 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 19:46:40 -0500 (EST)
Subject: [Tutor] Can't figure out why I'm getting no output??
References: <CA+KU-OEY=eQvocZs-xSWvT=BSGYxgpe8besiQAkH4xpUvWkJUQ@mail.gmail.com>
Message-ID: <lc9is4$8ne$2@ger.gmane.org>

 scurvy scott <stopitscurvy at gmail.com> Wrote in message:
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 

Please post as text, not html.

Try putting a print at the top of the code.  If it gets there and
 not to the last one, one of those lines is hanging.


-- 
DaveA


From denis.spir at gmail.com  Wed Jan 29 01:47:22 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 29 Jan 2014 01:47:22 +0100
Subject: [Tutor] If, elif, else
In-Reply-To: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
References: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
Message-ID: <52E84F9A.4020802@gmail.com>

On 01/28/2014 11:46 PM, Michael L. Pierre wrote:
> I am a newbie with Python (programming in general) and I am trying to create a program that will take user name and dob and pump out their age, while on a person's birthday the output not only states their name and age, but also prints out ***HAPPY BIRTHDAY***
> I have gotten it resolved to the point that it understands leap  years and gives the correct age. My problem arises when a date is input that is the current month, but a future date (i.e. today's date is 1/28/2014 but the input dob is 1/30/1967) It skips over the elif option to subtract one year and prints out ***HAPPY BIRTHDAY***
> I am only going to paste the non-leap year code, because the leap year code is basically identical.
>
> #Leapyear calculations/decision
> if leap_year != int:
>      age_month = int(current_split[1]) - int(dob_split[1])
>      #print age_month
>      if age_month != 0:
>          month_less = 1
>          age = int(current_split[0]) - int(dob_split[0]) - month_less
>          print "you are", age, "years old"
>      elif age_month == 0 and int(current_split[2]) > int(dob_split[2]):
>          age = int(current_split[0]) - int(dob_split[0]) - month_less
>          print "you are", age, "years old"
>      else:
>         age = int(current_split[0]) - int(dob_split[0])
>         print "You are", age, "and today is your birthday ***HAPPY BIRTHDAY***"
>
> Any help would be greatly appreciated :)

This is not an answer to your question, just some notes (which may help for this 
issue and others). The number one problem in programming is certainly 
understandability, or clarity for short. Programming is very hard (and quality 
very low) because we have major problems to understand what the code *actually* 
means, even often our own code while we're at it (not to mention a few weeks 
later, or years). We should do our best to reduce complication and obscurity as 
much as possible (even to the point of reducing our ambitions in terms of scope 
or scale, functionality or sophistication).

* What about a comment explaining your logic here, also for yourself, in plain 
natural language? (obviously it's not obvious, firstly for yourself, else the 
bug would be obvious...)

* I cannot guess what "if leap_year != int" may mean. (But I note you know, 
apparently, that int is a python type and int() acts like a function producing 
an int value.)

* You are using items of multi-item data 'current_split' and 'dob_split' 
(probably tuples) as key elements in the control of your application logic: why 
about naming these elements after their *meaning*? This would make the flow 
control clear, your understanding better, and your debugging, modifications, 
maintenance far easier? eg for instance
	year, month, day = current_split
[Or better create a Date type with year, month, day properties (or use python's, 
in the module datetime).]

* It's certainly acceptable to name something 'dob' in code (provided you 
comment it), but not in the text of a message on a mailing. (For whatever 
mysterious reason the meaning popped up in mind nevertheless, so _i_ don't need 
a translation anymore.)

* You don't need the "age_month == 0" sub-condition in the elif branch. (why?) 
(or your logic is wrong otherwise)

d

From davea at davea.name  Wed Jan 29 01:51:55 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 19:51:55 -0500 (EST)
Subject: [Tutor] Installing Python on osx 10.9.1
References: <0F842DEE-0040-4F69-880C-9308E880626F@sandlininc.com>
Message-ID: <lc9j5v$8ne$3@ger.gmane.org>

 Aubri Sandlin <aubri at sandlininc.com> Wrote in message:
> I have installed Python.  When I open IDLE I get this warning:  >>> WARNING: The version of Tcl/Tk (8.5.9) in use may be unstable.
> Visit http://www.python.org/download/mac/tcltk/ for current information.
> 
> 
> I have downloaded and installed the latest version of TCL/TK and rebooted my computer.  I still get the above warning.  
> 
> What else do I need to do in order to be able to use Python?
>
> 
> 

IDLE isn't an integral part of python.  I've never tried it in
 about five years of using Python. 

But if you think you need it, then tell people what version of
 Python and what version of (mac?) operating system.
 

-- 
DaveA


From dyoo at hashcollision.org  Wed Jan 29 01:45:35 2014
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 28 Jan 2014 16:45:35 -0800
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <CAArUT0iCQ1gFFqbdmiLtw0JoqPgu3SWQL7vWj3DQakEs16PX=w@mail.gmail.com>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
 <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
 <52E76A2D.8090408@gmail.com>
 <CAArUT0iCQ1gFFqbdmiLtw0JoqPgu3SWQL7vWj3DQakEs16PX=w@mail.gmail.com>
Message-ID: <CAGZAPF7f7fniCP3bkLDhkdfc7A-1onqoke96fygk7iO9RPL2Pw@mail.gmail.com>

Hi Denis,

Ok, stop for a moment.

Visit:    http://pythontutor.com/visualize.html

Specifically, here's your program:


http://pythontutor.com/visualize.html#code=a%3D%5B1,%5B1,2%5D%5D%0Ab%3Da%0Aa%3D%5B1,%5B2,3%5D%5D%0Aa%5B0%5D%3D0%0Aa%5B1%5D%3D%5B0,0%5D&mode=display&cumulative=false&heapPrimitives=false&drawParentPointers=false&textReferences=false&showOnlyOutputs=false&py=2&curInstr=3


Step through it, and see if anything there makes sense.  :P

Try a few more simple programs there, including the examples discussed
earlier on this thread.

I have a feeling that your mental model of what's happening is not
quite matching the machine, so the visualizer at
http://pythontutor.com/visualize.html may help bridge that gap.



Good luck!

From davea at davea.name  Wed Jan 29 02:06:51 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 20:06:51 -0500 (EST)
Subject: [Tutor] Installing Python on osx 10.9.1
References: <0F842DEE-0040-4F69-880C-9308E880626F@sandlininc.com>
 <lc9j5v$8ne$3@ger.gmane.org>
Message-ID: <lc9k1v$8ne$4@ger.gmane.org>

 Dave Angel <davea at davea.name> Wrote in message:
>  Aubri Sandlin <aubri at sandlininc.com> Wrote in message:
>> I have installed Python.  When I open IDLE I get this warning:  >>> WARNING: The version of Tcl/Tk (8.5.9) in use may be unstable.
>> Visit http://www.python.org/download/mac/tcltk/ for current information.
>> 
>> 
>> I have downloaded and installed the latest version of TCL/TK and rebooted my computer.  I still get the above warning.  
>> 
>> What else do I need to do in order to be able to use Python?
>>
>> 
>> 
> 
> IDLE isn't an integral part of python.  I've never tried it in
>  about five years of using Python. 
> 
> But if you think you need it, then tell people what version of
>  Python and what version of (mac?) operating system.
>  
Oops, I just noticed you give some of that information in the
 subject line. Sorry. 

But it'd be useful to know just what version of Tcl/Tj you tried
 to install.

You did realize that recent versions of os have a python
 installed,  like most systems other than Windows?
 


-- 
DaveA


From davea at davea.name  Wed Jan 29 02:10:02 2014
From: davea at davea.name (Dave Angel)
Date: Tue, 28 Jan 2014 20:10:02 -0500 (EST)
Subject: [Tutor] When is = a copy and when is it an alias
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
 <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
 <52E76A2D.8090408@gmail.com>
 <CAArUT0iCQ1gFFqbdmiLtw0JoqPgu3SWQL7vWj3DQakEs16PX=w@mail.gmail.com>
Message-ID: <lc9k7u$8ne$5@ger.gmane.org>

 Denis Heidtmann <denis.heidtmann at gmail.com> Wrote in message:
>
> 
 What is going on? ??I am more confused than I was a week ago.


Simple. spir has copy/paste editing errors. 

-- 
DaveA


From alan.gauld at btinternet.com  Wed Jan 29 02:19:54 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 01:19:54 +0000
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <CAArUT0iCQ1gFFqbdmiLtw0JoqPgu3SWQL7vWj3DQakEs16PX=w@mail.gmail.com>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
 <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
 <52E76A2D.8090408@gmail.com>
 <CAArUT0iCQ1gFFqbdmiLtw0JoqPgu3SWQL7vWj3DQakEs16PX=w@mail.gmail.com>
Message-ID: <lc9kvd$2na$1@ger.gmane.org>

On 28/01/14 19:00, Denis Heidtmann wrote:
> On Tue, Jan 28, 2014 at 12:28 AM, spir <denis.spir at gmail.com

This is getting confusing with two times Denis!

> <mailto:denis.spir at gmail.com>> wrote:
>
>                 a = [1,[2,3]]

I think the above line is a mistake. If Denis(spir) had missed
this out his code would work as he describes, but with it he
reassigns 'a' to a new list and, as you say breaks the connection.

If you forget about that line and keep a pointing at the original 
[1,[1,2]] list then the following code makes sense.

>                 a[0] = 0
>                 b
>
>     [0, [1, 2]]                  # this is where I get lost.
>
>                 a[1] = [0,0]
>                 b
>
>     [0, [0, 0]]


> My python gets a different result:

So does mine, and I suspect so does denis' (spir).
I think he made a mistake with the second assignment to a.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Wed Jan 29 02:24:03 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 01:24:03 +0000
Subject: [Tutor] subprocess.Popen help
In-Reply-To: <CACv9p5oySOtgro3Us0QLtbwmoNF6pFXbBso794jaK9TTi95yYA@mail.gmail.com>
References: <CACv9p5oySOtgro3Us0QLtbwmoNF6pFXbBso794jaK9TTi95yYA@mail.gmail.com>
Message-ID: <lc9l76$2na$3@ger.gmane.org>

On 28/01/14 19:52, leam hall wrote:
> Python tutorial for 2.6 (using 2.4 -- don't ask), first code blurb under 17.1.1
>
> http://docs.python.org/2.6/library/subprocess.html?highlight=subprocess#subprocess.Popen
>
> How would you make an ssh to another box put data back in "p"? The
> goal is to run a shell command on a remote box and work with the
> output on the local host.

How do you do it outside of Python?
There is no great magic in Popen, it just reads/writes the
standard streams.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Wed Jan 29 02:28:07 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 01:28:07 +0000
Subject: [Tutor] Can't figure out why I'm getting no output??
In-Reply-To: <CA+KU-OEY=eQvocZs-xSWvT=BSGYxgpe8besiQAkH4xpUvWkJUQ@mail.gmail.com>
References: <CA+KU-OEY=eQvocZs-xSWvT=BSGYxgpe8besiQAkH4xpUvWkJUQ@mail.gmail.com>
Message-ID: <lc9leq$7uu$1@ger.gmane.org>

On 28/01/14 20:45, scurvy scott wrote:

> import requests
> from bs4 import BeautifulSoup as beautiful
>
> payload = {'username': 'XXXXX', 'password': 'XXXXXX'}
> r = requests.post("http://dogehouse.org/index.php?page=login", data=payload)
> soup = beautiful(r.text)
> confirmed = str(soup.findAll('span',{'class':'confirmed'}))
>
> print "Confirmed account balance" +confirmed[86:98]

> I've tested the code in the regular python interpreter and it all
> executes the way it should. But when I attempt to run it using "python
> whatever.py" it doesn't give me any output.

Can you clarify what you mean by not giving any output?
Does the print statement print "Confirmed account balance"
with no further data? Or does it not even do that?

Does the OS prompt return? or does it just hang?
Are there any error messages, either from Python or from the OS?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Wed Jan 29 02:22:14 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 01:22:14 +0000
Subject: [Tutor] Importing Pygame
In-Reply-To: <CAAJkYqeLkPtLUQwWrLuJ58ogDJ9LRZ5otaFg=Hhx1B+6rav-OA@mail.gmail.com>
References: <DUB111-W9162F91EAA4A9FD227CE4097AD0@phx.gbl>
 <CAAJkYqeLkPtLUQwWrLuJ58ogDJ9LRZ5otaFg=Hhx1B+6rav-OA@mail.gmail.com>
Message-ID: <lc9l3p$2na$2@ger.gmane.org>

On 28/01/14 20:47, Glenn Lester wrote:
> I think you typed a comma instead of a period when you coded import
> pygame.sys
> Or it may be my display. Check it out.

No, it was deliberate. He was importing pygame *and* sys.
A comma separated import list is fine.

I agree with Dave it looks like there are two Python installs
fighting with each other somewhere. One has PyGame installed
the other doesn't (or can't see it).

But we need more details to be sure.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Wed Jan 29 02:47:59 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 01:47:59 +0000
Subject: [Tutor] If, elif, else
In-Reply-To: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
References: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
Message-ID: <lc9mk2$k9t$1@ger.gmane.org>

On 28/01/14 22:46, Michael L. Pierre wrote:
> I am a newbie with Python (programming in general)

Welcome to the list.

> I have gotten it resolved to the point that it understands leap  years
> and gives the correct age.

OK, I'll believe you, at least for now... :-)

>  My problem arises when a date is input that
> is the current month, but a future date (i.e. today?s date is 1/28/2014
> but the input dob is 1/30/1967)

I don;t understand that. How is 1967 a future date?
Do you just mean the fact that the day is bigger than todays day?

> It skips over the elif option to
> subtract one year and prints out ***HAPPY BIRTHDAY***

Unfortunately  its hard to tell exactly whats going on
because we can't see where much of the data comes from.
I'll make a few comments below but I'm not sure if they will help 
pinpoint your main issue.

> if leap_year != int:

No idea what this is supposed to be doing?
It is comparing leap_year to a type object.
I doubt very much if this 'if' test ever fails.

>      age_month = int(current_split[1]) - int(dob_split[1])

No idea what current_split or dob_split are. Since you are
converting them to int I'll assume string lists maybe?

>      if age_month != 0:
>          month_less = 1
>          age = int(current_split[0]) - int(dob_split[0]) - month_less
>          print "you are", age, "years old"
>
>      elif age_month == 0 and int(current_split[2]) > int(dob_split[2]):
>          age = int(current_split[0]) - int(dob_split[0]) - month_less

Note that you use month_less here even though you don't assign it a 
value as you did in the if block.
Does it already have a value or is that an oversight?

>          print "you are", age, "years old"

>      else:
>         age = int(current_split[0]) - int(dob_split[0])
>         print "You are", age, "and today is your birthday ***HAPPY
> BIRTHDAY***"

I assume you haven't found the datetime module yet?
It will take much of the hassle of date/time calculations away.
Or maybe you are doing it the hard way as a learning exercise?
That's OK too. :-)

A final thought. It might be worth putting some debug print
statements in so you can see what the values in the tsts are.

eg just before the if block put

print 'age_month = ', age_month

Also instead of relying on arithmetic you could maybe create some 
intermediate values.
Instead of
int(current_split[0]) - int(dob_split[0])

being calculated twice store it as a value, maybe called 
month_difference or similar?

It all helps make the code clearer and therefore easier
to debug.

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From denis.spir at gmail.com  Wed Jan 29 04:04:51 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 29 Jan 2014 04:04:51 +0100
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <lc9k7u$8ne$5@ger.gmane.org>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
 <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
 <52E76A2D.8090408@gmail.com>
 <CAArUT0iCQ1gFFqbdmiLtw0JoqPgu3SWQL7vWj3DQakEs16PX=w@mail.gmail.com>
 <lc9k7u$8ne$5@ger.gmane.org>
Message-ID: <52E86FD3.4010602@gmail.com>

On 01/29/2014 02:10 AM, Dave Angel wrote:
>   Denis Heidtmann <denis.heidtmann at gmail.com> Wrote in message:
>>
>>
>   What is going on?  I am more confused than I was a week ago.
>
>
> Simple. spir has copy/paste editing errors.

Oops! sorry

d

From eryksun at gmail.com  Wed Jan 29 08:15:05 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 29 Jan 2014 02:15:05 -0500
Subject: [Tutor] subprocess.Popen help
In-Reply-To: <CACv9p5oySOtgro3Us0QLtbwmoNF6pFXbBso794jaK9TTi95yYA@mail.gmail.com>
References: <CACv9p5oySOtgro3Us0QLtbwmoNF6pFXbBso794jaK9TTi95yYA@mail.gmail.com>
Message-ID: <CACL+1atj1ZyR=FUFtCgeKwR1uQwSA5h_Smiw0H4gHqSUMZfdyA@mail.gmail.com>

On Tue, Jan 28, 2014 at 2:52 PM, leam hall <leamhall at gmail.com> wrote:
> Python tutorial for 2.6 (using 2.4 -- don't ask), first code blurb under 17.1.1
>
> http://docs.python.org/2.6/library/subprocess.html?highlight=subprocess#subprocess.Popen
>
> How would you make an ssh to another box put data back in "p"? The
> goal is to run a shell command on a remote box and work with the
> output on the local host.

To run a single command via ssh, you may not need to script a fake tty
(as w/ pexpect). That's presuming you use the sshpass program or have
ssh-agent set up, along with keys created and copied by ssh-keygen and
ssh-copy-id.

    from subprocess import Popen, PIPE

    args = ['ssh', 'localhost', 'uname', '-o']
    kwds = dict(stdout=PIPE, stderr=PIPE)
    p = Popen(args, **kwds)

    ####

    >>> p.wait()
    0
    >>> p.stdout.read()
    'GNU/Linux\n'

To script an interactive shell more generally, you probably do want a
fake tty, such as pexpect with the pxssh module. Older versions will
work in Python 2.4. A more robust choice is Fabric, which uses the
Paramiko SSH2 library. But Fabric requires Python 2.5+.

http://pexpect.readthedocs.org
http://fabric.readthedocs.org

From denis.heidtmann at gmail.com  Wed Jan 29 02:34:13 2014
From: denis.heidtmann at gmail.com (Denis Heidtmann)
Date: Tue, 28 Jan 2014 17:34:13 -0800
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <lc9kvd$2na$1@ger.gmane.org>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
 <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
 <52E76A2D.8090408@gmail.com>
 <CAArUT0iCQ1gFFqbdmiLtw0JoqPgu3SWQL7vWj3DQakEs16PX=w@mail.gmail.com>
 <lc9kvd$2na$1@ger.gmane.org>
Message-ID: <CAArUT0jgdHntdzsTx5TYu+5g9=SHmOqhGrXSxJcV0XVYm=MWag@mail.gmail.com>

On Tue, Jan 28, 2014 at 5:19 PM, Alan Gauld <alan.gauld at btinternet.com>wrote:

> On 28/01/14 19:00, Denis Heidtmann wrote:
>
>> On Tue, Jan 28, 2014 at 12:28 AM, spir <denis.spir at gmail.com
>>
>
> This is getting confusing with two times Denis!
>
>  <mailto:denis.spir at gmail.com>> wrote:
>>
>>                 a = [1,[2,3]]
>>
>
> I think the above line is a mistake. If Denis(spir) had missed
> this out his code would work as he describes, but with it he
> reassigns 'a' to a new list and, as you say breaks the connection.
>
> If you forget about that line and keep a pointing at the original
> [1,[1,2]] list then the following code makes sense.
>
>
>                  a[0] = 0
>>                 b
>>
>>     [0, [1, 2]]                  # this is where I get lost.
>>
>>                 a[1] = [0,0]
>>                 b
>>
>>     [0, [0, 0]]
>>
>
>
>  My python gets a different result:
>>
>
> So does mine, and I suspect so does denis' (spir).
> I think he made a mistake with the second assignment to a.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.flickr.com/photos/alangauldphotos


Glad to hear it.  That is what I was hoping, but I did not want to question
a helpful person.

-Denis H.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140128/ef712413/attachment.html>

From gb.gabrielebrambilla at gmail.com  Wed Jan 29 03:09:30 2014
From: gb.gabrielebrambilla at gmail.com (Gabriele Brambilla)
Date: Tue, 28 Jan 2014 21:09:30 -0500
Subject: [Tutor] reading files
Message-ID: <CABmgkieJFyWx8w1g78sTZT-=bkVWg=ZQndzm5L13LsFGPKO4vw@mail.gmail.com>

Hi,
how could I read float numbers if the data format is like this (using
readline):

1.05519999999995        1.26758123387023        -0.314470329249235
-0.293015360064208      6.15795761907822        1.92919102133526
13.0780459630378        2.15175351758512e6

the numbers aren't equally spaced and they had not the same number of
figures...

thanks

Gabriele
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140128/91017e22/attachment.html>

From mmadlavana at uh.edu  Wed Jan 29 07:04:18 2014
From: mmadlavana at uh.edu (Mkhanyisi Madlavana)
Date: Wed, 29 Jan 2014 08:04:18 +0200
Subject: [Tutor] subprocess.Popen help
In-Reply-To: <CACv9p5oySOtgro3Us0QLtbwmoNF6pFXbBso794jaK9TTi95yYA@mail.gmail.com>
References: <CACv9p5oySOtgro3Us0QLtbwmoNF6pFXbBso794jaK9TTi95yYA@mail.gmail.com>
Message-ID: <CAD5sEnfeD6PJfcfU746Jr9nFP4oCxgr6bcJsphBTSh-xeRUxSA@mail.gmail.com>

On 28 January 2014 21:52, leam hall <leamhall at gmail.com> wrote:

> Python tutorial for 2.6 (using 2.4 -- don't ask), first code blurb under
> 17.1.1
>
>
> http://docs.python.org/2.6/library/subprocess.html?highlight=subprocess#subprocess.Popen
>
> How would you make an ssh to another box put data back in "p"? The
> goal is to run a shell command on a remote box and work with the
> output on the local host.
>

Popen is not meant for that. You should try the paramiko library.
http://www.lag.net/paramiko/
http://jessenoller.com/blog/2009/02/05/ssh-programming-with-paramiko-completely-different

Cheers
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140129/4dd56878/attachment.html>

From stopitscurvy at gmail.com  Wed Jan 29 03:12:28 2014
From: stopitscurvy at gmail.com (scurvy scott)
Date: Tue, 28 Jan 2014 21:12:28 -0500
Subject: [Tutor] Code runs in interpreter but won't output to stdout
Message-ID: <CA+KU-OG3MhsgVhTRswLQsFMqY2Hz+SAAjpVo45H8OsFcReSs1w@mail.gmail.com>

Hi guys, I'm trying to figure out why my code won't output to terminal, but
will run just fine in interpreter.
I'm using python 2.7.3 on Debian Linux/Crunchbang.

Here is my code.

import requests
from bs4 import BeautifulSoup as beautiful
import sys

def dogeScrape(username, password):
    payload = {'username': username, 'password': password}
    r = requests.post("http://dogehouse.org/index.php?page=login",
data=payload)
    soup = beautiful(r.text)
    confirmed = str(soup.findAll('span',{'class':'confirmed'}))
    print "Confirmed account balance: " + confirmed[86:98]

dogeScrape("XXXX", "XXXX")

It will output the "confirmed....." part, just not the confirmed variable.
It will output the entire thing in the interpreter.

I initially ran this without being in a function with the username/password
stuff hardcoded to see if the rest of the scraper would run, it still never
output to stdout.

Any help would be appreciated.

Also, as an aside, is there a terminal/command line parsing library someone
could recommend? I've been looking at optparse but maybe some of you will
have other ideas.

thanks a lot,
Scott
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140128/d25a3f93/attachment.html>

From alan.gauld at btinternet.com  Wed Jan 29 15:08:30 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Wed, 29 Jan 2014 14:08:30 +0000
Subject: [Tutor] reading files
In-Reply-To: <CABmgkieJFyWx8w1g78sTZT-=bkVWg=ZQndzm5L13LsFGPKO4vw@mail.gmail.com>
References: <CABmgkieJFyWx8w1g78sTZT-=bkVWg=ZQndzm5L13LsFGPKO4vw@mail.gmail.com>
Message-ID: <lcb20i$nc0$1@ger.gmane.org>

On 29/01/14 02:09, Gabriele Brambilla wrote:
> how could I read float numbers if the data format is like this (using
> readline):
>
> 1.05519999999995        1.26758123387023        -0.314470329249235
> -0.293015360064208      6.15795761907822        1.92919102133526


> the numbers aren't equally spaced and they had not the same number of
> figures...

Just read the lines as strings and use str.split() to split them on 
whitespace. You will wind up with a list of numeric strings that
can be converted using float()

If you need more info just ask about the specific issue you get
stuck on (reading, splitting, converting etc).

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From breamoreboy at yahoo.co.uk  Wed Jan 29 15:16:07 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 29 Jan 2014 14:16:07 +0000
Subject: [Tutor] reading files
In-Reply-To: <CABmgkieJFyWx8w1g78sTZT-=bkVWg=ZQndzm5L13LsFGPKO4vw@mail.gmail.com>
References: <CABmgkieJFyWx8w1g78sTZT-=bkVWg=ZQndzm5L13LsFGPKO4vw@mail.gmail.com>
Message-ID: <lcb2et$vrj$1@ger.gmane.org>

On 29/01/2014 02:09, Gabriele Brambilla wrote:
> Hi,
> how could I read float numbers if the data format is like this (using
> readline):
>
> 1.05519999999995        1.26758123387023        -0.314470329249235
> -0.293015360064208      6.15795761907822        1.92919102133526
> 13.0780459630378        2.15175351758512e6
>
> the numbers aren't equally spaced and they had not the same number of
> figures...
>
> thanks
>
> Gabriele
>

Something like this, untested:-

floats = []
with open('myfile') as infile:
     for line in infile:
         floats.extend(float(f) for f in line.split())

-- 
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 Jan 29 15:32:31 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 30 Jan 2014 01:32:31 +1100
Subject: [Tutor] If, elif, else
In-Reply-To: <lc9ik7$8ne$1@ger.gmane.org>
References: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
 <lc9ik7$8ne$1@ger.gmane.org>
Message-ID: <20140129143231.GB3799@ando>

On Tue, Jan 28, 2014 at 07:42:25PM -0500, Dave Angel wrote:
>  "Michael L. Pierre" <Michael.Pierre at ccpoa.org> Wrote in message:
> > _______________________________________________
> > Tutor maillist  -  Tutor at python.org
> > To unsubscribe or change subscription options:
> > https://mail.python.org/mailman/listinfo/tutor
> > 
> 
> Start by posting in text form, since this is a text group.  You
>  apparently posted in html. And you doublespaced.

Sorry Dave, your tools are letting you down again. Michael did in fact 
post with plain text. His original email included both a text/plain part 
and a text/html part.

Now I'm no friend of posting in HTML, I think it's a poor idea from both 
a technical and social perspective, but I also realise that the horse 
has bolted on that one. The best we can hope for is for mail clients to 
do the right thing when posting in HTML and also provide a plain text 
version. If your client is unable to deal with that, you need a better 
client.


> Any reason you didn't use the date module?  The code would have
>  been much simpler. 

'Cos he's a newbie and probably doesn't know about the date module :-)



-- 
Steven

From denis.spir at gmail.com  Wed Jan 29 15:18:45 2014
From: denis.spir at gmail.com (spir)
Date: Wed, 29 Jan 2014 15:18:45 +0100
Subject: [Tutor] When is = a copy and when is it an alias
In-Reply-To: <CAArUT0jgdHntdzsTx5TYu+5g9=SHmOqhGrXSxJcV0XVYm=MWag@mail.gmail.com>
References: <CAArUT0jhow_mqWKD_ZcKNWCLTKAHwTu1U5G1_8Q+OMbOuCxbAQ@mail.gmail.com>
 <52E62C84.4000308@gmail.com>
 <CAArUT0j3y4tjcJJotmMPd2odv5OCWTYpiJ3-BvJvheX8qY-Mpg@mail.gmail.com>
 <52E76A2D.8090408@gmail.com>
 <CAArUT0iCQ1gFFqbdmiLtw0JoqPgu3SWQL7vWj3DQakEs16PX=w@mail.gmail.com>
 <lc9kvd$2na$1@ger.gmane.org>
 <CAArUT0jgdHntdzsTx5TYu+5g9=SHmOqhGrXSxJcV0XVYm=MWag@mail.gmail.com>
Message-ID: <52E90DC5.7030803@gmail.com>

On 01/29/2014 02:34 AM, Denis Heidtmann wrote:
> Glad to hear it.  That is what I was hoping, but I did not want to question
> a helpful person.

(you could & should, we need helpful feedback too, to improve our skills; i 
mean, as long as it's honest indeed)

d

From gb.gabrielebrambilla at gmail.com  Wed Jan 29 15:50:09 2014
From: gb.gabrielebrambilla at gmail.com (Gabriele Brambilla)
Date: Wed, 29 Jan 2014 09:50:09 -0500
Subject: [Tutor] reading files
In-Reply-To: <lcb2et$vrj$1@ger.gmane.org>
References: <CABmgkieJFyWx8w1g78sTZT-=bkVWg=ZQndzm5L13LsFGPKO4vw@mail.gmail.com>
 <lcb2et$vrj$1@ger.gmane.org>
Message-ID: <CABmgkicAHFSgPk1vFfCMFNFFxh+dpSyU5F7EiCmMy3gzyKcV+Q@mail.gmail.com>

thanks to everyone, I've used David's method.

Gabriele


2014-01-29 Mark Lawrence <breamoreboy at yahoo.co.uk>

> On 29/01/2014 02:09, Gabriele Brambilla wrote:
>
>> Hi,
>> how could I read float numbers if the data format is like this (using
>> readline):
>>
>> 1.05519999999995        1.26758123387023        -0.314470329249235
>> -0.293015360064208      6.15795761907822        1.92919102133526
>> 13.0780459630378        2.15175351758512e6
>>
>> the numbers aren't equally spaced and they had not the same number of
>> figures...
>>
>> thanks
>>
>> Gabriele
>>
>>
> Something like this, untested:-
>
> floats = []
> with open('myfile') as infile:
>     for line in infile:
>         floats.extend(float(f) for f in line.split())
>
> --
> My fellow Pythonistas, ask not what our language can do for you, ask what
> you can do for our language.
>
> Mark Lawrence
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140129/eb9a8b1e/attachment.html>

From shahmed at sfwmd.gov  Wed Jan 29 16:18:29 2014
From: shahmed at sfwmd.gov (Ahmed, Shakir)
Date: Wed, 29 Jan 2014 15:18:29 +0000
Subject: [Tutor] help with data insert into Access table
Message-ID: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>

Hi,

I am trying to insert a record in the access table, the value has a quote and could not insert the record. Any idea how I can insert records like this quotes.

Thanks
S


cursor.execute("INSERT INTO PicsPostInfo(Pics_name) values ('Site Name's Harbor.JPG')")
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access Driver] Syntax error (missing operator) in query expression ''Site Name's Harbor.JPG')'. (-3100) (SQLExecDirectW)")


We value your opinion. Please take a few minutes to share your comments on the service you received from the District by clicking on this link<http://my.sfwmd.gov/portal/page/portal/pg_grp_surveysystem/survey%20ext?pid=1653>.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140129/b7599199/attachment.html>

From davea at davea.name  Wed Jan 29 16:40:09 2014
From: davea at davea.name (Dave Angel)
Date: Wed, 29 Jan 2014 10:40:09 -0500 (EST)
Subject: [Tutor] If, elif, else
References: <92315E4127E74E4BBF1C52EB866B6C9B4A400634@SACTO-EXCH02.ccpoa.org>
 <lc9ik7$8ne$1@ger.gmane.org> <20140129143231.GB3799@ando>
Message-ID: <lcb77d$vfg$1@ger.gmane.org>

 Steven D'Aprano <steve at pearwood.info> Wrote in message:

> 
> Sorry Dave, your tools are letting you down again. Michael did in fact 
> post with plain text. His original email included both a text/plain part 
> and a text/html part.
> 
> Now I'm no friend of posting in HTML, I think it's a poor idea from both 
> a technical and social perspective, but I also realise that the horse 
> has bolted on that one. The best we can hope for is for mail clients to 
> do the right thing when posting in HTML and also provide a plain text 
> version. If your client is unable to deal with that, you need a better 
> client.
> 
> 

On android,  I'm using "nntp NewsReader". The author already fixed
 two other problems,  but this one is that replies to many
 messages will not copy the quoted part. All that gets copied is
 the tutor boilerplate. 

For now I'll just abort my replies when that happens. 


>> 
> 


-- 
DaveA


From breamoreboy at yahoo.co.uk  Wed Jan 29 17:07:37 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 29 Jan 2014 16:07:37 +0000
Subject: [Tutor] reading files
In-Reply-To: <CABmgkicAHFSgPk1vFfCMFNFFxh+dpSyU5F7EiCmMy3gzyKcV+Q@mail.gmail.com>
References: <CABmgkieJFyWx8w1g78sTZT-=bkVWg=ZQndzm5L13LsFGPKO4vw@mail.gmail.com>
 <lcb2et$vrj$1@ger.gmane.org>
 <CABmgkicAHFSgPk1vFfCMFNFFxh+dpSyU5F7EiCmMy3gzyKcV+Q@mail.gmail.com>
Message-ID: <lcb8vv$heq$1@ger.gmane.org>

On 29/01/2014 14:50, Gabriele Brambilla wrote:
> thanks to everyone, I've used David's method.
>
> Gabriele
>
> 2014-01-29 Mark Lawrence <breamoreboy at yahoo.co.uk
> <mailto:breamoreboy at yahoo.co.uk>>
>
>     On 29/01/2014 02:09, Gabriele Brambilla wrote:
>
>         Hi,
>         how could I read float numbers if the data format is like this
>         (using
>         readline):
>
>         1.05519999999995        1.26758123387023        -0.314470329249235
>         -0.293015360064208      6.15795761907822        1.92919102133526
>         13.0780459630378        2.15175351758512e6
>
>         the numbers aren't equally spaced and they had not the same
>         number of
>         figures...
>
>         thanks
>
>         Gabriele
>
>
>     Something like this, untested:-
>
>     floats = []
>     with open('myfile') as infile:
>          for line in infile:
>              floats.extend(float(f) for f in line.split())
>
>     --
>     My fellow Pythonistas, ask not what our language can do for you, ask
>     what you can do for our language.
>
>     Mark Lawrence
>

Please don't top post.

FTR what is David's method and who is David?

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

Mark Lawrence


From __peter__ at web.de  Wed Jan 29 17:46:43 2014
From: __peter__ at web.de (Peter Otten)
Date: Wed, 29 Jan 2014 17:46:43 +0100
Subject: [Tutor] help with data insert into Access table
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
Message-ID: <lcbb8n$ls3$1@ger.gmane.org>

Ahmed, Shakir wrote:

> I am trying to insert a record in the access table, the value has a quote
> and could not insert the record. Any idea how I can insert records like
> this quotes.

> cursor.execute("INSERT INTO PicsPostInfo(Pics_name) values ('Site Name's
> Harbor.JPG')") Traceback (most recent call last):
>   File "<interactive input>", line 1, in <module>
> ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access
> Driver] Syntax error (missing operator) in query expression ''Site Name's
> Harbor.JPG')'. (-3100) (SQLExecDirectW)")

Every compliant database module has a paramstyle attribute, e. g. for 
sqlite3:

>>> import sqlite3
>>> sqlite3.paramstyle
'qmark'

"qmark" means that you use "?" instead of the actual value.
http://www.python.org/dev/peps/pep-0249/ has a list of available 
`paramstyle`s.

Assuming that the database driver you are using uses "qmark" your code would 
become

cursor.execute("INSERT INTO PicsPostInfo(Pics_name) VALUES (?)",
               ("Site Name's Harbor.JPG",))

i. e. in addition to the SQL statement there is a tuple (in this case a 1-
tuple, the trailing comma is necessary!) holding the values. This way is the 
only reasonable way to go when the actual data is provided by your users 
because it prevents SQL injection attacks.

See also http://xkcd.com/327/



From breamoreboy at yahoo.co.uk  Wed Jan 29 18:11:37 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 29 Jan 2014 17:11:37 +0000
Subject: [Tutor] help with data insert into Access table
In-Reply-To: <lcbb8n$ls3$1@ger.gmane.org>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
 <lcbb8n$ls3$1@ger.gmane.org>
Message-ID: <lcbco0$9qo$1@ger.gmane.org>

On 29/01/2014 16:46, Peter Otten wrote:
> Ahmed, Shakir wrote:
>
>> I am trying to insert a record in the access table, the value has a quote
>> and could not insert the record. Any idea how I can insert records like
>> this quotes.
>
>> cursor.execute("INSERT INTO PicsPostInfo(Pics_name) values ('Site Name's
>> Harbor.JPG')") Traceback (most recent call last):
>>    File "<interactive input>", line 1, in <module>
>> ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access
>> Driver] Syntax error (missing operator) in query expression ''Site Name's
>> Harbor.JPG')'. (-3100) (SQLExecDirectW)")
>
> Every compliant database module has a paramstyle attribute, e. g. for
> sqlite3:
>
>>>> import sqlite3
>>>> sqlite3.paramstyle
> 'qmark'
>
> "qmark" means that you use "?" instead of the actual value.
> http://www.python.org/dev/peps/pep-0249/ has a list of available
> `paramstyle`s.
>
> Assuming that the database driver you are using uses "qmark" your code would
> become
>
> cursor.execute("INSERT INTO PicsPostInfo(Pics_name) VALUES (?)",
>                 ("Site Name's Harbor.JPG",))
>
> i. e. in addition to the SQL statement there is a tuple (in this case a 1-
> tuple, the trailing comma is necessary!) holding the values. This way is the
> only reasonable way to go when the actual data is provided by your users
> because it prevents SQL injection attacks.
>
> See also http://xkcd.com/327/
>

I think it's worth pointing out that there is a difference here between 
the OP's 'Site Name's Harbor.JPG' and Peter's "Site Name's Harbor.JPG". 
  Left as homework for the newbies :)

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

Mark Lawrence


From reuben.dlink at gmail.com  Wed Jan 29 18:15:53 2014
From: reuben.dlink at gmail.com (Reuben)
Date: Wed, 29 Jan 2014 22:45:53 +0530
Subject: [Tutor] Project directory structure
Message-ID: <CAN89AcormiJowQ1O3h8Ycy2n2cNwVKU+D_EfYmWv6u3YVt9gMQ@mail.gmail.com>

Hi,

Do we need to follow any particular directory structure for creating any
New projects or could we just randomly create a folder containing the
script of interest?

Regards,
Reuben
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140129/65f6833e/attachment.html>

From shahmed at sfwmd.gov  Wed Jan 29 19:14:45 2014
From: shahmed at sfwmd.gov (Ahmed, Shakir)
Date: Wed, 29 Jan 2014 18:14:45 +0000
Subject: [Tutor] help with data insert into Access table
In-Reply-To: <lcbb8n$ls3$1@ger.gmane.org>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
 <lcbb8n$ls3$1@ger.gmane.org>
Message-ID: <554ED400F994BF43AD3E6ED0328200BA7ABEB747@whqembx03p.ad.sfwmd.gov>

Thanks, it worked exactly what I was trying to do so.

-----Original Message-----
From: Tutor [mailto:tutor-bounces+shahmed=sfwmd.gov at python.org] On Behalf Of Peter Otten
Sent: Wednesday, January 29, 2014 11:47 AM
To: tutor at python.org
Subject: Re: [Tutor] help with data insert into Access table

Ahmed, Shakir wrote:

> I am trying to insert a record in the access table, the value has a quote
> and could not insert the record. Any idea how I can insert records like
> this quotes.

> cursor.execute("INSERT INTO PicsPostInfo(Pics_name) values ('Site Name's
> Harbor.JPG')") Traceback (most recent call last):
>   File "<interactive input>", line 1, in <module>
> ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access
> Driver] Syntax error (missing operator) in query expression ''Site Name's
> Harbor.JPG')'. (-3100) (SQLExecDirectW)")

Every compliant database module has a paramstyle attribute, e. g. for
sqlite3:

>>> import sqlite3
>>> sqlite3.paramstyle
'qmark'

"qmark" means that you use "?" instead of the actual value.
http://www.python.org/dev/peps/pep-0249/ has a list of available
`paramstyle`s.

Assuming that the database driver you are using uses "qmark" your code would
become

cursor.execute("INSERT INTO PicsPostInfo(Pics_name) VALUES (?)",
               ("Site Name's Harbor.JPG",))

i. e. in addition to the SQL statement there is a tuple (in this case a 1-
tuple, the trailing comma is necessary!) holding the values. This way is the
only reasonable way to go when the actual data is provided by your users
because it prevents SQL injection attacks.

See also http://xkcd.com/327/





We value your opinion. Please take a few minutes to share your comments on the service you received from the District by clicking on this link<http://my.sfwmd.gov/portal/page/portal/pg_grp_surveysystem/survey%20ext?pid=1653>.


From keithwins at gmail.com  Wed Jan 29 20:47:55 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 29 Jan 2014 14:47:55 -0500
Subject: [Tutor] help with data insert into Access table
In-Reply-To: <lcbco0$9qo$1@ger.gmane.org>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
 <lcbb8n$ls3$1@ger.gmane.org> <lcbco0$9qo$1@ger.gmane.org>
Message-ID: <CAO5ffbZSyq81WS0hVE--pcyokPxzEYidDNLJ2vdbuSRpSj5qTA@mail.gmail.com>

On Wed, Jan 29, 2014 at 12:11 PM, Mark Lawrence <breamoreboy at yahoo.co.uk> wrote:
> I think it's worth pointing out that there is a difference here between the
> OP's 'Site Name's Harbor.JPG' and Peter's "Site Name's Harbor.JPG".  Left as
> homework for the newbies :)


I'll bite. But are you just referring to the tuple issue, reinforced
by the XKCD, that Peter referred to, or have I not finished this
homework?

-- 
Keith

From breamoreboy at yahoo.co.uk  Wed Jan 29 21:03:58 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Wed, 29 Jan 2014 20:03:58 +0000
Subject: [Tutor] help with data insert into Access table
In-Reply-To: <CAO5ffbZSyq81WS0hVE--pcyokPxzEYidDNLJ2vdbuSRpSj5qTA@mail.gmail.com>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
 <lcbb8n$ls3$1@ger.gmane.org> <lcbco0$9qo$1@ger.gmane.org>
 <CAO5ffbZSyq81WS0hVE--pcyokPxzEYidDNLJ2vdbuSRpSj5qTA@mail.gmail.com>
Message-ID: <lcbmr5$app$1@ger.gmane.org>

On 29/01/2014 19:47, Keith Winston wrote:
> On Wed, Jan 29, 2014 at 12:11 PM, Mark Lawrence <breamoreboy at yahoo.co.uk> wrote:
>> I think it's worth pointing out that there is a difference here between the
>> OP's 'Site Name's Harbor.JPG' and Peter's "Site Name's Harbor.JPG".  Left as
>> homework for the newbies :)
>
>
> I'll bite. But are you just referring to the tuple issue, reinforced
> by the XKCD, that Peter referred to, or have I not finished this
> homework?
>

Nothing to do with tuples.  Tools such as syntax checkers or MkI 
eyeballs come in useful here.  Although such tools probably won't pick 
up the incorrect spelling of "harboUr" :)

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

Mark Lawrence


From keithwins at gmail.com  Wed Jan 29 21:53:22 2014
From: keithwins at gmail.com (Keith Winston)
Date: Wed, 29 Jan 2014 15:53:22 -0500
Subject: [Tutor] help with data insert into Access table
In-Reply-To: <lcbmr5$app$1@ger.gmane.org>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
 <lcbb8n$ls3$1@ger.gmane.org> <lcbco0$9qo$1@ger.gmane.org>
 <CAO5ffbZSyq81WS0hVE--pcyokPxzEYidDNLJ2vdbuSRpSj5qTA@mail.gmail.com>
 <lcbmr5$app$1@ger.gmane.org>
Message-ID: <CAO5ffbb9k8T2-0k7_b86xW89ETY+sfg=x-5jW1SCNi+=mv3p0g@mail.gmail.com>

On Wed, Jan 29, 2014 at 3:03 PM, Mark Lawrence <breamoreboy at yahoo.co.uk> wrote:
> Nothing to do with tuples.  Tools such as syntax checkers or MkI eyeballs
> come in useful here.  Although such tools probably won't pick up the
> incorrect spelling of "harboUr" :)

Alas, now I'm more confused. I don't see any mispellings in what you
referred to? I had the impression that Peter was employing tuples
because, as an immutable type, it couldn't
inadvertently/inauspiciously be changed by a user. Oh, I see... single
vs. double, eh? Got it.


-- 
Keith

From bgailer at gmail.com  Wed Jan 29 23:24:23 2014
From: bgailer at gmail.com (bob gailer)
Date: Wed, 29 Jan 2014 17:24:23 -0500
Subject: [Tutor] Code runs in interpreter but won't output to stdout
In-Reply-To: <CA+KU-OG3MhsgVhTRswLQsFMqY2Hz+SAAjpVo45H8OsFcReSs1w@mail.gmail.com>
References: <CA+KU-OG3MhsgVhTRswLQsFMqY2Hz+SAAjpVo45H8OsFcReSs1w@mail.gmail.com>
Message-ID: <52E97F97.8080705@gmail.com>

On 1/28/2014 9:12 PM, scurvy scott wrote:
> Hi guys, I'm trying to figure out why my code won't output to 
> terminal, but will run just fine in interpreter.
> I'm using python 2.7.3 on Debian Linux/Crunchbang.
>
> Here is my code.
>
> import requests
> from bs4 import BeautifulSoup as beautiful
> import sys
>
> def dogeScrape(username, password):
>     payload = {'username': username, 'password': password}
>     r = requests.post("http://dogehouse.org/index.php?page=login", 
> data=payload)
>     soup = beautiful(r.text)
>     confirmed = str(soup.findAll('span',{'class':'confirmed'}))
>     print "Confirmed account balance: " + confirmed[86:98]
>
> dogeScrape("XXXX", "XXXX")
>
> It will output the "confirmed....." part, just not the confirmed 
> variable. It will output the entire thing in the interpreter.
>
Good reminder for everyone: be explicit about behavior. We wasted an 
iteration just to get this clarified.

The expression to be printed is the concatenation of "Confirmed account 
balance: " with a slice of confirmed. Therefore confirmed is less that 
86 characters (or the slice is blank), therefore no output appears. 
Print the entire value of confirmed; that will tell us a lot.

From eryksun at gmail.com  Wed Jan 29 23:26:51 2014
From: eryksun at gmail.com (eryksun)
Date: Wed, 29 Jan 2014 17:26:51 -0500
Subject: [Tutor] help with data insert into Access table
In-Reply-To: <CAO5ffbb9k8T2-0k7_b86xW89ETY+sfg=x-5jW1SCNi+=mv3p0g@mail.gmail.com>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEB6A2@whqembx03p.ad.sfwmd.gov>
 <lcbb8n$ls3$1@ger.gmane.org> <lcbco0$9qo$1@ger.gmane.org>
 <CAO5ffbZSyq81WS0hVE--pcyokPxzEYidDNLJ2vdbuSRpSj5qTA@mail.gmail.com>
 <lcbmr5$app$1@ger.gmane.org>
 <CAO5ffbb9k8T2-0k7_b86xW89ETY+sfg=x-5jW1SCNi+=mv3p0g@mail.gmail.com>
Message-ID: <CACL+1av5g+trcPg5STiDb2h6z5FrnJykFsDiCtkQ2n-4poDsWg@mail.gmail.com>

On Wed, Jan 29, 2014 at 3:53 PM, Keith Winston <keithwins at gmail.com> wrote:
> I had the impression that Peter was employing tuples because,
> as an immutable type, it couldn't inadvertently/inauspiciously
> be changed by a user

Per footnote 5 of PEP 249, the parameters need to be in a type that
supports __getitem__ (sequence or mapping). In addition to the qmark
paramstyle, pysqlite (the development name for the sqlite3 module)
supports named parameters:

http://docs.python.org/3/library/sqlite3#sqlite3.Cursor.execute

For a tuple or list of parameters, pysqlite uses the PyTuple and
PyList concrete APIs, respectively. Else for tuple/list subclasses, or
other sequence types, it uses the abstract PySequence API.

Tuples are the sequence of choice because they're allocated more
efficiently, with deallocated tuples cached by size (up to length 20).
Additionally, a tuple of constants is stored directly in the code
object (allowed because it's immutable), while a list has to be built
each time the code is evaluate. For example:

    >>> code = (lambda: ("Site Name's Harbor.JPG",)).__code__

    >>> code.co_consts
    (None, "Site Name's Harbor.JPG", ("Site Name's Harbor.JPG",))

For a dict with named parameters, pysqlite uses the PyDict concrete
API. For a dict subclass (e.g. defaultdict, OrderedDict) it falls back
on the abstract PyMapping API.

Relevant sqlite3 C APIs:

    sqlite3_bind_parameter_count
    sqlite3_bind_parameter_name

https://www.sqlite.org/c3ref/bind_parameter_count.html
https://www.sqlite.org/c3ref/bind_parameter_name.html

    sqlite3_bind_null
    sqlite3_bind_int64
    sqlite3_bind_double
    sqlite3_bind_text
    sqlite3_bind_blob

https://www.sqlite.org/c3ref/bind_blob.html

From dpalao.python at gmail.com  Wed Jan 29 23:53:50 2014
From: dpalao.python at gmail.com (David Palao)
Date: Wed, 29 Jan 2014 23:53:50 +0100
Subject: [Tutor] reading files
In-Reply-To: <lcb8vv$heq$1@ger.gmane.org>
References: <CABmgkieJFyWx8w1g78sTZT-=bkVWg=ZQndzm5L13LsFGPKO4vw@mail.gmail.com>
 <lcb2et$vrj$1@ger.gmane.org>
 <CABmgkicAHFSgPk1vFfCMFNFFxh+dpSyU5F7EiCmMy3gzyKcV+Q@mail.gmail.com>
 <lcb8vv$heq$1@ger.gmane.org>
Message-ID: <CAKUKWz=YMscO17xLPMUseAMOJVb059hTzRm8G2WVwU8juAWxpw@mail.gmail.com>

2014-01-29 Mark Lawrence <breamoreboy at yahoo.co.uk>:
> On 29/01/2014 14:50, Gabriele Brambilla wrote:
>>
>> thanks to everyone, I've used David's method.
>>
>> Gabriele
>>
>> 2014-01-29 Mark Lawrence <breamoreboy at yahoo.co.uk
>> <mailto:breamoreboy at yahoo.co.uk>>
>>
>>
>>     On 29/01/2014 02:09, Gabriele Brambilla wrote:
>>
>>         Hi,
>>         how could I read float numbers if the data format is like this
>>         (using
>>         readline):
>>
>>         1.05519999999995        1.26758123387023        -0.314470329249235
>>         -0.293015360064208      6.15795761907822        1.92919102133526
>>         13.0780459630378        2.15175351758512e6
>>
>>         the numbers aren't equally spaced and they had not the same
>>         number of
>>         figures...
>>
>>         thanks
>>
>>         Gabriele
>>
>>
>>     Something like this, untested:-
>>
>>     floats = []
>>     with open('myfile') as infile:
>>          for line in infile:
>>              floats.extend(float(f) for f in line.split())
>>
>>     --
>>     My fellow Pythonistas, ask not what our language can do for you, ask
>>     what you can do for our language.
>>
>>     Mark Lawrence
>>
>
> Please don't top post.
>
> FTR what is David's method and who is David?
>
>
> --
> My fellow Pythonistas, ask not what our language can do for you, ask what
> you can do for our language.
>
> Mark Lawrence
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

I guess he refers to my email, the first answer to his question.

Best regards.

From dpalao.python at gmail.com  Wed Jan 29 23:55:37 2014
From: dpalao.python at gmail.com (David Palao)
Date: Wed, 29 Jan 2014 23:55:37 +0100
Subject: [Tutor] Fwd:  reading files
In-Reply-To: <CAKUKWzn=OG-qs1v-9Ym4Khc_5yyGZ4SoPRE1oxa_0D7egV8iYQ@mail.gmail.com>
References: <CABmgkieJFyWx8w1g78sTZT-=bkVWg=ZQndzm5L13LsFGPKO4vw@mail.gmail.com>
 <CAKUKWzn=OG-qs1v-9Ym4Khc_5yyGZ4SoPRE1oxa_0D7egV8iYQ@mail.gmail.com>
Message-ID: <CAKUKWzkhRsW4yjpiBp14kVQBfSqFOzVpeCD9m4gf3dHL+T9OVQ@mail.gmail.com>

...that I forgot to send to the mailing list...


---------- Forwarded message ----------
From: David Palao <dpalao.python at gmail.com>
Date: 2014-01-29
Subject: Re: [Tutor] reading files
To: Gabriele Brambilla <gb.gabrielebrambilla at gmail.com>


Hi,
One possibility I can think of: If you make one string with one line
of your input, like
s = "1.05519999999995        1.26758123387023
-0.314470329249235 -0.293015360064208      6.15795761907822
1.92919102133526 13.0780459630378        2.15175351758512e6"
then
L = [float(i) for i in s.split()]
is a list of the floats you are looking for.

Best.

2014-01-29 Gabriele Brambilla <gb.gabrielebrambilla at gmail.com>:
> Hi,
> how could I read float numbers if the data format is like this (using
> readline):
>
> 1.05519999999995        1.26758123387023        -0.314470329249235
> -0.293015360064208      6.15795761907822        1.92919102133526
> 13.0780459630378        2.15175351758512e6
>
> the numbers aren't equally spaced and they had not the same number of
> figures...
>
> thanks
>
> Gabriele
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From bill at celestial.net  Thu Jan 30 03:45:18 2014
From: bill at celestial.net (Bill Campbell)
Date: Wed, 29 Jan 2014 18:45:18 -0800
Subject: [Tutor] imaplib and mutt flags
Message-ID: <20140130024518.GA16149@ayn.mi.celestial.com>

I'm writing a python script which uses imaplib to select all
unseen messages from a mail folder to process some messages
flagging them as seen, and leaving others as unseen so they can
be manually processed using the 'mutt' mail client.

After some trial and error, I've figured out how to remove the
\Seen flag from messages I want to look at manually, but I still
have a bit of a problem in that when I open the folder with mutt
using direct access to the Maildir folder in the file system,
mutt flags these parsed but unseen messages with the 'O' instead
of 'N' which is uses for new messages.

I would like to have the script restore the 'N' status flag that
mutt uses instead of 'O'.

The mail server is using courier-imap with Maildir stores on
CentOS Linux.  Mutt access is direct on the file system, not via
IMAP.

Bill
-- 
INTERNET:   bill at celestial.com  Bill Campbell; Celestial Software LLC
URL: http://www.celestial.com/  PO Box 820; 6641 E. Mercer Way
Voice:          (206) 236-1676  Mercer Island, WA 98040-0820
Fax:            (206) 232-9186  Skype: jwccsllc (206) 855-5792

Political language... is designed to make lies sound truthful and
murder respectable, and to give an appearance of solidity to pure
wind. -- George Orwell

From ben+python at benfinney.id.au  Thu Jan 30 05:16:52 2014
From: ben+python at benfinney.id.au (Ben Finney)
Date: Thu, 30 Jan 2014 15:16:52 +1100
Subject: [Tutor] Python shell wont open IDLE or an exisiting .py files
References: <774101.57561.bm@smtp216.mail.gq1.yahoo.com>
 <lcchev$hi3$1@ger.gmane.org>
Message-ID: <85a9eecde3.fsf@benfinney.id.au>

Terry Reedy <tjreedy at udel.edu> writes:

> On 1/29/2014 6:26 PM, shangonichols at sbcglobal.net wrote:
> >  > If I launch the Python GUI it opens a Python Shell fine. But as
> >  > soon as I try to open a file (including a "new" file), it closes
> >  > the Shell.
>
> This I do not. What is 'Python GUI'? What is 'Python Shell'?

Those are (part of) the names of menu entries created by the Python
installer for MS Windows. I am not sure exactly what programs they
invoke.

-- 
 \       ?? whoever claims any right that he is unwilling to accord to |
  `\             his fellow-men is dishonest and infamous.? ?Robert G. |
_o__)           Ingersoll, _The Liberty of Man, Woman and Child_, 1877 |
Ben Finney


From eryksun at gmail.com  Thu Jan 30 06:52:00 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 30 Jan 2014 00:52:00 -0500
Subject: [Tutor] Python shell wont open IDLE or an exisiting .py files
In-Reply-To: <85a9eecde3.fsf@benfinney.id.au>
References: <774101.57561.bm@smtp216.mail.gq1.yahoo.com>
 <lcchev$hi3$1@ger.gmane.org> <85a9eecde3.fsf@benfinney.id.au>
Message-ID: <CACL+1aswteO0j_vtNR_bXOfKLvc9-67zZJ2d2y4VgDu=B7ujLg@mail.gmail.com>

On Wed, Jan 29, 2014 at 11:16 PM, Ben Finney <ben+python at benfinney.id.au> wrote:
> Terry Reedy <tjreedy at udel.edu> writes:
>
>> This I do not. What is 'Python GUI'? What is 'Python Shell'?
>
> Those are (part of) the names of menu entries created by the Python
> installer for MS Windows. I am not sure exactly what programs they
> invoke.

The above reply was cross-posted from the following thread on python-list:

https://mail.python.org/pipermail/python-list/2014-January/thread.html#665549

The Windows start menu has a shortcut for "IDLE (Python GUI)" that
runs the idle.pyw script. The file extension .pyw is associated with
either pythonw.exe or the launcher pyw.exe, which are both linked as
GUI programs. That means the process is created without an attached
console (one can be allocated or attached later using Windows API
calls).

idle.pyw imports idlelib.PyShell and calls its `main`. The shell
itself is implemented by the PyShell class, for which the window title
is

    "Python " + platform.python_version() + " Shell"

http://hg.python.org/cpython/file/c3896275c0f6/Lib/idlelib/PyShell.py#l829

Also, the editor window's run menu has a "Python Shell" item:

    ('run', [('Python Shell', '<<open-python-shell>>')])

http://hg.python.org/cpython/file/c3896275c0f6/Lib/idlelib/Bindings.py#l59

From alan.gauld at btinternet.com  Thu Jan 30 10:27:33 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 30 Jan 2014 09:27:33 +0000
Subject: [Tutor] imaplib and mutt flags
In-Reply-To: <20140130024518.GA16149@ayn.mi.celestial.com>
References: <20140130024518.GA16149@ayn.mi.celestial.com>
Message-ID: <lcd5to$4dc$1@ger.gmane.org>

On 30/01/14 02:45, Bill Campbell wrote:
> I'm writing a python script which uses imaplib

We don't get many messages about imaplib so I'm
not sure how many folks here know about it.

> After some trial and error, I've figured out how to remove the
> \Seen flag from messages I want to look at manually,

Then it's probably a good idea to post at least a code
extract showing us how you are going about that.
We work better when we have code to look at...

> have a bit of a problem in that when I open the folder with mutt
> using direct access to the Maildir folder in the file system,
> mutt flags these parsed but unseen messages with the 'O' instead
> of 'N' which is uses for new messages.

We have some mutt users so they may be able to p[itch in here.

> The mail server is using courier-imap with Maildir stores on
> CentOS Linux.  Mutt access is direct on the file system, not via
> IMAP.

OK, Final missing piece is which Python version?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From shangonichols at sbcglobal.net  Thu Jan 30 00:26:04 2014
From: shangonichols at sbcglobal.net (shangonichols at sbcglobal.net)
Date: Wed, 29 Jan 2014 23:26:04 +0000
Subject: [Tutor] =?utf-8?q?Python_shell_wont_open_IDLE_or_an_exisiting_=2E?=
	=?utf-8?q?py_files?=
Message-ID: <774101.57561.bm@smtp216.mail.gq1.yahoo.com>

I am on Windows 8, Python 3.3.4 and 3.3.3 and all previous versions exhibit the same problem on my Windows 8 PC. This problem occurred out of nowhere overnight. It was working fine for months until today.

>  I tried to open a file and nothing happened. If I tried to open a .py file
> (any .py file) from an existing instance of IDLE, it briefly flashed up a
> new window and then closed both the new window and the existing window
> (normally it opens the requested in a new window leaving the existing window
> untouched).
>
> If I launch the Python GUI it opens a Python Shell fine. But as soon as I
> try to open a file (including a "new" file), it closes the Shell.
>
> I rebooted the machine. Same problem.
>
> I repaired the Python installation and rebooted. Same problem.
>
> I uninstalled Python. Rebooted. Deleted the Python33 directory entirely.
> Rebooted. Installed Python. Rebooted. Same problem.
>
> Everything else on the system appears to be working just fine.
>
> Any ideas what the problem might be or how else I might go about fixing
> things?








Sent from Windows Mail
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140129/e924a881/attachment.html>

From zemke at yahoo.com  Wed Jan 29 22:58:04 2014
From: zemke at yahoo.com (danz)
Date: Wed, 29 Jan 2014 13:58:04 -0800 (PST)
Subject: [Tutor] getUncPath(mappedDrive)
In-Reply-To: <4F6E49E3.6060604@timgolden.me.uk>
References: <1332620033.41135.YahooMailNeo@web110704.mail.gq1.yahoo.com>
 <4F6E2CF6.6030205@timgolden.me.uk>
 <1332624583.21709.YahooMailNeo@web110712.mail.gq1.yahoo.com>
 <4F6E49E3.6060604@timgolden.me.uk>
Message-ID: <1391032684086-5045727.post@n6.nabble.com>

Tim.

I came across your code while searching for a similar need.  Your post was
the best I could find on the subject.  Perhaps more importantly, you showed
me that going down the ctypes rabbit hole can be less intimidating than I
assumed.  Thanks!

My use case was a little different than the original poster's.  I need to
retrieve the network paths for all of the mapped drives that are currently
connected.  I chose a different implementation, that seems to work well.  I
would appreciate any comments you have on this approach.

BTW, Thank you for the information on your website.  Your information and
pointers to GetDriveType() and GetVolumeInformation() helped me a a lot.

Dan

-------------------
import subprocess

def available_network_drives():
    net_drives = dict()
    for line in subprocess.check_output(['net', 'use']).splitlines():
        if line.startswith('OK'):
            fields = line.split()
            net_drives[fields[1]] = fields[2]   # [1] == key, [2] ==
net_path
    return net_drives
    
print available_network_drives()



--
View this message in context: http://python.6.x6.nabble.com/Tutor-getUncPath-mappedDrive-tp4652304p5045727.html
Sent from the Python - tutor mailing list archive at Nabble.com.

From amydavidson at sympatico.ca  Wed Jan 29 23:19:51 2014
From: amydavidson at sympatico.ca (Amy Davidson)
Date: Wed, 29 Jan 2014 17:19:51 -0500
Subject: [Tutor] Python Mastermind Help
Message-ID: <BLU0-SMTP2674D6234A48133ABA730CC8AC0@phx.gbl>

Hello,

I?ve been given an assignment in which I need to recreate the game Mastermind. I?ve been attempting it for approx a week with little to no progress. I was hoping someone would be able to point me in the right direction.

here is what I?ve got:

import random

def masterMind():
    userGuess = raw_input("Guess my 5 digit password:?)

    while True:
        if len(userGuess) != 5:
           userGuess = input("Guess my 5 digit password:?)

Much appreciated.

AD

From rafael.knuth at gmail.com  Thu Jan 30 12:11:56 2014
From: rafael.knuth at gmail.com (Rafael Knuth)
Date: Thu, 30 Jan 2014 12:11:56 +0100
Subject: [Tutor] Split Method
Message-ID: <CAM-E2X4dmGUXhUGxCAFpgwxJd8QWzQ=mgp7Mbf-z_darEf1BAA@mail.gmail.com>

Hey there,

I am having some issues with splitting strings.
I already know how to split strings that are separated through empty spaces:

def SplitMyStrings():
    Colors = "red blue green white black".split()
    return (Colors)

print(SplitMyStrings())

>>>
['red', 'blue', 'green', 'white', 'black']

... however I couldn't figure out how to split each character into a list item.
This is what I want to get as a result:

>>>
['r', 'e', 'd', 'b', 'l', 'u', 'e', 'g', 'r', 'e', 'e', 'n', 'w', 'h',
'i', 't', 'e', 'b', 'l', 'a', 'c', 'k']

I am using Python 3.3.0
Thanks in advance!

All the best,

Raf

From steve at pearwood.info  Thu Jan 30 12:22:21 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 30 Jan 2014 22:22:21 +1100
Subject: [Tutor] Split Method
In-Reply-To: <CAM-E2X4dmGUXhUGxCAFpgwxJd8QWzQ=mgp7Mbf-z_darEf1BAA@mail.gmail.com>
References: <CAM-E2X4dmGUXhUGxCAFpgwxJd8QWzQ=mgp7Mbf-z_darEf1BAA@mail.gmail.com>
Message-ID: <20140130112221.GD3799@ando>

On Thu, Jan 30, 2014 at 12:11:56PM +0100, Rafael Knuth wrote:
> Hey there,
> 
> I am having some issues with splitting strings.
> I already know how to split strings that are separated through empty spaces:
> 
> def SplitMyStrings():
>     Colors = "red blue green white black".split()
>     return (Colors)
> 
> print(SplitMyStrings())
> 
> >>>
> ['red', 'blue', 'green', 'white', 'black']
> 
> ... however I couldn't figure out how to split each character into a list item.

list(some_string)

For example:

py> list("hello world")
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']


Note that the space is considered an ordinary character. If you want to 
ignore spaces:

py> list("hello world".replace(" ", ""))
['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']


-- 
Steven

From __peter__ at web.de  Thu Jan 30 12:22:42 2014
From: __peter__ at web.de (Peter Otten)
Date: Thu, 30 Jan 2014 12:22:42 +0100
Subject: [Tutor] Split Method
References: <CAM-E2X4dmGUXhUGxCAFpgwxJd8QWzQ=mgp7Mbf-z_darEf1BAA@mail.gmail.com>
Message-ID: <lcdcl1$lbn$1@ger.gmane.org>

Rafael Knuth wrote:

> Hey there,
> 
> I am having some issues with splitting strings.
> I already know how to split strings that are separated through empty
> spaces:
> 
> def SplitMyStrings():
>     Colors = "red blue green white black".split()
>     return (Colors)
> 
> print(SplitMyStrings())
> 
>>>>
> ['red', 'blue', 'green', 'white', 'black']
> 
> ... however I couldn't figure out how to split each character into a list
> item. This is what I want to get as a result:
> 
>>>>
> ['r', 'e', 'd', 'b', 'l', 'u', 'e', 'g', 'r', 'e', 'e', 'n', 'w', 'h',
> 'i', 't', 'e', 'b', 'l', 'a', 'c', 'k']

>>> colors = "red blue green white black"
>>> list(colors)
['r', 'e', 'd', ' ', 'b', 'l', 'u', 'e', ' ', 'g', 'r', 'e', 'e', 'n', ' ', 
'w', 'h', 'i', 't', 'e', ' ', 'b', 'l', 'a', 'c', 'k']

If you don't want the spaces remove them before

>>> list(colors.replace(" ", ""))
['r', 'e', 'd', 'b', 'l', 'u', 'e', 'g', 'r', 'e', 'e', 'n', 'w', 'h', 'i', 
't', 'e', 'b', 'l', 'a', 'c', 'k']

or while

[c for c in colors if not c.isspace()]
['r', 'e', 'd', 'b', 'l', 'u', 'e', 'g', 'r', 'e', 'e', 'n', 'w', 'h', 'i', 
't', 'e', 'b', 'l', 'a', 'c', 'k']

converting to a list. Note that c.isspace() is true for all whitespace 
chars; use [... if c != " "] if you want to omit " " only.


From steve at pearwood.info  Thu Jan 30 12:18:30 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 30 Jan 2014 22:18:30 +1100
Subject: [Tutor] Project directory structure
In-Reply-To: <CAN89AcormiJowQ1O3h8Ycy2n2cNwVKU+D_EfYmWv6u3YVt9gMQ@mail.gmail.com>
References: <CAN89AcormiJowQ1O3h8Ycy2n2cNwVKU+D_EfYmWv6u3YVt9gMQ@mail.gmail.com>
Message-ID: <20140130111830.GC3799@ando>

On Wed, Jan 29, 2014 at 10:45:53PM +0530, Reuben wrote:
> Hi,
> 
> Do we need to follow any particular directory structure for creating any
> New projects or could we just randomly create a folder containing the
> script of interest?

Yes and no.

If all you're doing is writing a single file script, you don't even need 
a folder at all. Just create it, well, just about anywhere you like.

If you're creating something a little more formal, say you plan to make 
it public, there is a convention for laying out project directories:

myproject
+-- CHANGES.txt
+-- LICENCE.txt
+-- MANIFEST.in  
+-- README.txt
+-- setup.py
+-- src
    +-- myproject.py


although the src directory is not compulsory.

If you're creating a package, rather than a single module, then you do 
need to use a special directory structure:

mypackage
+-- __init__.py
+-- __main__.py
+-- cheese.py
+-- eggs.py
+-- spam.py


The above is a package called "mypackage", containing the following 
modules:

mypackage
mypackage.cheese
mypackage.eggs
mypackage.spam

plus two special modules:

__init__.py is needed for Python to recognise this as a package, rather 
than a folder full of files; when you run `import mypackage`, it is 
the code inside __init__.py that runs.

__main__.py is used when you try to run mypackage as an executable file. 
When you run `python -m mypackage` from the shell, it runs the code in 
__main__.py.


But apart from that, pretty much anything goes.



-- 
Steven

From mail at timgolden.me.uk  Thu Jan 30 12:39:58 2014
From: mail at timgolden.me.uk (Tim Golden)
Date: Thu, 30 Jan 2014 11:39:58 +0000
Subject: [Tutor] getUncPath(mappedDrive)
In-Reply-To: <1391032684086-5045727.post@n6.nabble.com>
References: <1332620033.41135.YahooMailNeo@web110704.mail.gq1.yahoo.com>
 <4F6E2CF6.6030205@timgolden.me.uk>
 <1332624583.21709.YahooMailNeo@web110712.mail.gq1.yahoo.com>
 <4F6E49E3.6060604@timgolden.me.uk> <1391032684086-5045727.post@n6.nabble.com>
Message-ID: <52EA3A0E.10806@timgolden.me.uk>

On 29/01/2014 21:58, danz wrote:
> Tim.
> 
> I came across your code while searching for a similar need.  Your post was
> the best I could find on the subject.  Perhaps more importantly, you showed
> me that going down the ctypes rabbit hole can be less intimidating than I
> assumed.  Thanks!

[The OP appears to be replying via nabble to a tutor thread from about
18 months ago. I was the person doing most of the talking hence the
reply to me]

> 
> My use case was a little different than the original poster's.  I need to
> retrieve the network paths for all of the mapped drives that are currently
> connected.  I chose a different implementation, that seems to work well.  I
> would appreciate any comments you have on this approach.

[... snip subprocess "NET USE" + splitlines ...]

It's a perfectly reasonable approach. The usual caveats would apply:
that you're at the mercy of layout changes in "NET USE" and of i18n
changes to the "OK" text. But both of those are low risk and if it works
for you and you're in control of your environment, then it's fine.

There's something somewhat satisfying in employing the underlying API
for what should be a future-proof solution, but parsing stdout is a
well-established approach as well.

> BTW, Thank you for the information on your website.  Your information and
> pointers to GetDriveType() and GetVolumeInformation() helped me a a lot.

You're welcome. Glad it was useful.


TJG

From mail at timgolden.me.uk  Thu Jan 30 12:49:24 2014
From: mail at timgolden.me.uk (Tim Golden)
Date: Thu, 30 Jan 2014 11:49:24 +0000
Subject: [Tutor] getUncPath(mappedDrive)
In-Reply-To: <52EA3A0E.10806@timgolden.me.uk>
References: <1332620033.41135.YahooMailNeo@web110704.mail.gq1.yahoo.com>
 <4F6E2CF6.6030205@timgolden.me.uk>
 <1332624583.21709.YahooMailNeo@web110712.mail.gq1.yahoo.com>
 <4F6E49E3.6060604@timgolden.me.uk> <1391032684086-5045727.post@n6.nabble.com>
 <52EA3A0E.10806@timgolden.me.uk>
Message-ID: <52EA3C44.1010001@timgolden.me.uk>

On 30/01/2014 11:39, Tim Golden wrote:
> On 29/01/2014 21:58, danz wrote:
>> Tim.
>>
>> I came across your code while searching for a similar need.  Your post was
>> the best I could find on the subject.  Perhaps more importantly, you showed
>> me that going down the ctypes rabbit hole can be less intimidating than I
>> assumed.  Thanks!
> 
> [The OP appears to be replying via nabble to a tutor thread from about
> 18 months ago. I was the person doing most of the talking hence the
> reply to me]

Just by way of an alternative, the code outlined here:

http://timgolden.me.uk/python/win32_how_do_i/show_mapped_drives.html

will produce the same effect as your parsing of the "net use" output.

TJG

From alan.gauld at btinternet.com  Thu Jan 30 13:07:56 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Thu, 30 Jan 2014 12:07:56 +0000
Subject: [Tutor] Python Mastermind Help
In-Reply-To: <BLU0-SMTP2674D6234A48133ABA730CC8AC0@phx.gbl>
References: <BLU0-SMTP2674D6234A48133ABA730CC8AC0@phx.gbl>
Message-ID: <lcdfaf$nd1$1@ger.gmane.org>

On 29/01/14 22:19, Amy Davidson wrote:
> I?ve been given an assignment in which I need to recreate
 > the game Mastermind.

OK I assume you know how mastermind works?
ie the rules of the game.

> I?ve been attempting it for approx a week with little to no progress.
 > I was hoping someone would be able to point me in the right direction.

OK, Start by writing down an example of what the finished
game should look like. Maybe a welcome message followed by
a prompt for input. An example input and the games response
and so on until it completes.

That will act as a specification for your program.

> here is what I?ve got:
>
> import random

I assume you plan on using random to generate the target pattern?
For now I'd start with a fixed pattern, generating a random one is best 
left to the end otherwise testing behaviour will be slightly more difficult.

> def masterMind():
>      userGuess = raw_input("Guess my 5 digit password:?)
>
>      while True:
>          if len(userGuess) != 5:
>             userGuess = input("Guess my 5 digit password:?)


When you create a "while True" loop its vital that you provide some way 
to exit. I usually code the exit clause immediately after creating
the loop.

Your loop has no exit so it just loops forever.
If the len() is not 5 you get a prompt and another attempt
but if it does equal 5 the loop just spins silently.

Your next steps should be:
1) Clarify in your mind what the program should do (see above)
2) create a means of exiting the loop
3) create a target to guess
4) start comparing the user input to the target. ( I suggest
you create a second function to do that, you can then test
it in isolation)

Let us know how you get on.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From bill at celestial.net  Thu Jan 30 17:44:24 2014
From: bill at celestial.net (Bill Campbell)
Date: Thu, 30 Jan 2014 08:44:24 -0800
Subject: [Tutor] imaplib and mutt flags
In-Reply-To: <lcd5to$4dc$1@ger.gmane.org>
References: <20140130024518.GA16149@ayn.mi.celestial.com>
 <lcd5to$4dc$1@ger.gmane.org>
Message-ID: <20140130164424.GA29925@ayn.mi.celestial.com>

On Thu, Jan 30, 2014, Alan Gauld wrote:
> On 30/01/14 02:45, Bill Campbell wrote:
>> I'm writing a python script which uses imaplib
>
> We don't get many messages about imaplib so I'm
> not sure how many folks here know about it.

I've used it off and on for years, but still don't know much
about it :-).

>> After some trial and error, I've figured out how to remove the
>> \Seen flag from messages I want to look at manually,
>
> Then it's probably a good idea to post at least a code
> extract showing us how you are going about that.
> We work better when we have code to look at...
>
>> have a bit of a problem in that when I open the folder with mutt
>> using direct access to the Maildir folder in the file system,
>> mutt flags these parsed but unseen messages with the 'O' instead
>> of 'N' which is uses for new messages.
>
> We have some mutt users so they may be able to p[itch in here.
>
>> The mail server is using courier-imap with Maildir stores on
>> CentOS Linux.  Mutt access is direct on the file system, not via
>> IMAP.
>
> OK, Final missing piece is which Python version?

On this machine, Python 2.4.6.

It seems my main problem is more related to the way that
courier-imap and mutt handle the Maildir stores.  Mutt
distinguishes unread messages as 'N' where the messages are in
the $folder/new directory and 'O' in $folder/cur, and moves them
from cur to new when one manually changes the flag to 'N'.

The IMAP protocol hides the mail store so one cannot manage the
message files as this depends on the physical storage format,
Maildir, UW IMAP, etc.

The bottom line is that this isn't an imaplib/python problem.

Bill
-- 
INTERNET:   bill at celestial.com  Bill Campbell; Celestial Software LLC
URL: http://www.celestial.com/  PO Box 820; 6641 E. Mercer Way
Voice:          (206) 236-1676  Mercer Island, WA 98040-0820
Fax:            (206) 232-9186  Skype: jwccsllc (206) 855-5792

The problems we face today are there because the people who work for a
living are now outnumbered by those who vote for a living. -- Anonymous

From duxbuz at hotmail.com  Thu Jan 30 16:43:49 2014
From: duxbuz at hotmail.com (Ian D)
Date: Thu, 30 Jan 2014 15:43:49 +0000
Subject: [Tutor] importing my module imports only one function
Message-ID: <DUB123-W50803ADC21B4FF250203CDCBAF0@phx.gbl>

if I create a module called "modtest.py" like this:
 
import turtle
 
def square():
    for i in range(4):
        turtle.fd(100)
        turtle.lt(90)
 
def tri():
    for i in range(3):
        turtle.fd(100)
        turtle.lt(120)
 
 
if __name__ == "__main__":
    
    tri()
 
And then call it like this:
 
import sys
sys.path.append("D:\python\modules")
import  modtest
 
modtest.square()
modtest.tri()
 
why would I just get ability to call the 'square()' function and not the 'tri()' function.
 
I get a square and a trace back:
 
line 7, in <module>
    modtest.tri()
AttributeError: 'module' object has no attribute 'tri'
 
 
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140130/1601318c/attachment.html>

From zemke at yahoo.com  Thu Jan 30 14:13:20 2014
From: zemke at yahoo.com (danz)
Date: Thu, 30 Jan 2014 05:13:20 -0800 (PST)
Subject: [Tutor] getUncPath(mappedDrive)
In-Reply-To: <1391032684086-5045727.post@n6.nabble.com>
References: <1332620033.41135.YahooMailNeo@web110704.mail.gq1.yahoo.com>
 <4F6E2CF6.6030205@timgolden.me.uk>
 <1332624583.21709.YahooMailNeo@web110712.mail.gq1.yahoo.com>
 <4F6E49E3.6060604@timgolden.me.uk> <1391032684086-5045727.post@n6.nabble.com>
Message-ID: <1391087600750-5045785.post@n6.nabble.com>

I apologize to all, but my above code won't work with paths that have
embedded spaces.  It also turns out that the "net use" command inserts a
carriage-return/line-feed between the Path and Network fields when the last
character position of the Path exceeds 80 characters.

My above approach seemed  simpler, but that's just because I posted it
before adequate testing.  Unfortunately, in order to make it actually work
for all cases, the implementation becomes more complex and begins to look
like a kludge.  So my recommendation is to use Tim's ctypes approach.



--
View this message in context: http://python.6.x6.nabble.com/Tutor-getUncPath-mappedDrive-tp4652304p5045785.html
Sent from the Python - tutor mailing list archive at Nabble.com.

From alan.gauld at btinternet.com  Fri Jan 31 02:07:01 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 31 Jan 2014 01:07:01 +0000
Subject: [Tutor] importing my module imports only one function
In-Reply-To: <DUB123-W50803ADC21B4FF250203CDCBAF0@phx.gbl>
References: <DUB123-W50803ADC21B4FF250203CDCBAF0@phx.gbl>
Message-ID: <lcesv8$og2$1@ger.gmane.org>

On 30/01/14 15:43, Ian D wrote:
> if I create a module called "modtest.py" like this:
>
> import turtle
>
> def square():

> def tri():
>
> if __name__ == "__main__":
>
>      tri()
>
> And then call it like this:
>
> import  modtest
>
> modtest.square()
> modtest.tri()
>
> why would I just get ability to call the 'square()' function and not the
> 'tri()' function.

Are you by any chance testing this from inside an IDE and added the 
tri() fuinction after the square one?

If so I'd suggest shutting down the IDE and restarting.
You may be seeing the old module imported prior to your
adding tri()

There is a reload()??? function for reloading modules that have
already been loaded to avoid this kind of thing but I don't
trust it entirely so if in doubt shut the IDE down and
restart...

Or just try running it in the command line interpreter
instead...

Assuming my guess at the cause is correct of course.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From eryksun at gmail.com  Fri Jan 31 02:58:59 2014
From: eryksun at gmail.com (eryksun)
Date: Thu, 30 Jan 2014 20:58:59 -0500
Subject: [Tutor] getUncPath(mappedDrive)
In-Reply-To: <1391087600750-5045785.post@n6.nabble.com>
References: <1332620033.41135.YahooMailNeo@web110704.mail.gq1.yahoo.com>
 <4F6E2CF6.6030205@timgolden.me.uk>
 <1332624583.21709.YahooMailNeo@web110712.mail.gq1.yahoo.com>
 <4F6E49E3.6060604@timgolden.me.uk> <1391032684086-5045727.post@n6.nabble.com>
 <1391087600750-5045785.post@n6.nabble.com>
Message-ID: <CACL+1avT-_pkkdWtq5jGV_JjHvJFQCr+n3G-P7WrwUBD8hTVvg@mail.gmail.com>

On Thu, Jan 30, 2014 at 8:13 AM, danz <zemke at yahoo.com> wrote:
> I apologize to all, but my above code won't work with paths that have
> embedded spaces.  It also turns out that the "net use" command inserts a
> carriage-return/line-feed between the Path and Network fields when the last
> character position of the Path exceeds 80 characters.
>
> My above approach seemed  simpler, but that's just because I posted it
> before adequate testing.  Unfortunately, in order to make it actually work
> for all cases, the implementation becomes more complex and begins to look
> like a kludge.  So my recommendation is to use Tim's ctypes approach.

You could use WMI's Win32_LogicalDisk class [1]. One way is to parse
CSV output from wmic.exe [2]:

    wmic LogicalDisk WHERE "DriveType=4" ^
    GET DeviceID, ProviderName /format:csv

You can parse the output using the csv module. Or use Tim's wmi module [3]:

    import wmi

    DRIVE_REMOTE = 4

    def available_network_drives():
        net_drives = dict()
        c = wmi.WMI()
        for drive in c.Win32_LogicalDisk(DriveType=DRIVE_REMOTE):
            net_drives[drive.DeviceID] = drive.ProviderName
        return net_drives

[1] http://msdn.microsoft.com/en-us/library/aa394173
[2] http://ss64.com/nt/wmic.html
[3] http://timgolden.me.uk/python/wmi/index.html

From davea at davea.name  Fri Jan 31 04:10:16 2014
From: davea at davea.name (Dave Angel)
Date: Thu, 30 Jan 2014 22:10:16 -0500 (EST)
Subject: [Tutor] importing my module imports only one function
References: <DUB123-W50803ADC21B4FF250203CDCBAF0@phx.gbl>
Message-ID: <lcf40b$o3h$1@ger.gmane.org>

 Ian D <duxbuz at hotmail.com> Wrote in message:
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 

1) you forgot to escape the backslashes in your module path.
 Either use forward slashes,  double them, or use a raw string.
 

2) Perhaps you have more than one such file in your path.
 Temporarily add a print to it, or examine modtest.__file__.  Less
 likely,  you might have a spurious. pyc file lying around.
 

And if you post in text mode, I might be able to quote some of
 your code and be more specific. 

-- 
DaveA


From james at uplinkzero.com  Fri Jan 31 12:31:49 2014
From: james at uplinkzero.com (James Chapman)
Date: Fri, 31 Jan 2014 11:31:49 +0000
Subject: [Tutor] Unit testing infinite loops
Message-ID: <CAHvkzym41vLrsEVvZtFUDVEVnCmJ-nLWRZVs6td2GsTJMUU16w@mail.gmail.com>

Hello tutors

I've constructed an example which shows a problem I'm having testing a real
world program and would like to run it past you.

tutor_question.py
--------------------------------------
# -*- coding: utf-8 -*-
import sys
import threading
import time


class Time_Printer(threading.Thread):

    def run(self):
        for i in range(60):
            print('%s - %s' % (self, time.ctime(time.time())))
            time.sleep(1)


class Infinite_Loop_Tutor_Question(object):

    def start_A(self):
        thread = Time_Printer()
        thread.daemon = True
        thread.start()
        print('Started %s' % (thread))

    def start_B(self):
        thread = Time_Printer()
        thread.daemon = True
        thread.start()
        print('Started %s' % (thread))

    def run_forever(self):
        self.start_A()
        time.sleep(0.5)
        self.start_B()
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            print("Caught Keyboard Interrupt...")
            sys.exit(0)


if __name__ == '__main__':
    infinite_loop = Infinite_Loop_Tutor_Question()
    infinite_loop.run_forever()

--------------------------------------

In my example above, testing the everything but the run_forever method is
trivial.

So on to my question... The run_forever method essentially just fires up a
bunch of threads to serve various purposes and then waits for CTRL-C to
terminate the entire program. Testing this at the moment is very difficult
because the unit test ends up in the infinite loop. So, would a better idea
be to create an attribute, set it to True and then do

try:
    while self.attribute:
        time.sleep(1)
except KeyboardInterrupt:
    ...


My unit test could then set the attribute. However I'd still have the
problem of how I get from the unit test line that fires up the method to
the next line to change the attribute.

So how should the run_forever method be written so that it's testable, or
if it's testable as is, how would I test it?

And please, no comments about syntax, clean exits of threads, thread
communication, resources, or even the need for testing the run_forever
method. In my test I want to test that it makes the relevant calls and then
enters the infinite loop at which point I want to terminate it.

Thanks in advance, and hopefully there are no formatting issues this time.


--
James
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140131/5a454c37/attachment.html>

From denis.spir at gmail.com  Fri Jan 31 13:10:03 2014
From: denis.spir at gmail.com (spir)
Date: Fri, 31 Jan 2014 13:10:03 +0100
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: <CAHvkzym41vLrsEVvZtFUDVEVnCmJ-nLWRZVs6td2GsTJMUU16w@mail.gmail.com>
References: <CAHvkzym41vLrsEVvZtFUDVEVnCmJ-nLWRZVs6td2GsTJMUU16w@mail.gmail.com>
Message-ID: <52EB929B.2010809@gmail.com>

On 01/31/2014 12:31 PM, James Chapman wrote:
> try:
>      while self.attribute:
>          time.sleep(1)
> except KeyboardInterrupt:

Maybe I'm missing apoint or reasoning wrongly, but I'd rather do:

while self.attribute:
    try:
         time.sleep(1)
    except KeyboardInterrupt:

... or something like that however, (I don't know whether one can interrupt 
while sleeping)

d

From steve at pearwood.info  Fri Jan 31 13:32:43 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Fri, 31 Jan 2014 23:32:43 +1100
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: <52EB929B.2010809@gmail.com>
References: <CAHvkzym41vLrsEVvZtFUDVEVnCmJ-nLWRZVs6td2GsTJMUU16w@mail.gmail.com>
 <52EB929B.2010809@gmail.com>
Message-ID: <20140131123242.GK3799@ando>

On Fri, Jan 31, 2014 at 01:10:03PM +0100, spir wrote:
> I don't know whether one can interrupt while sleeping

py> from time import sleep
py> sleep(60*60*24*365)  # 1 year
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyboardInterrupt

Yes you can.



-- 
Steven

From eryksun at gmail.com  Fri Jan 31 13:57:55 2014
From: eryksun at gmail.com (eryksun)
Date: Fri, 31 Jan 2014 07:57:55 -0500
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: <CAHvkzym41vLrsEVvZtFUDVEVnCmJ-nLWRZVs6td2GsTJMUU16w@mail.gmail.com>
References: <CAHvkzym41vLrsEVvZtFUDVEVnCmJ-nLWRZVs6td2GsTJMUU16w@mail.gmail.com>
Message-ID: <CACL+1atOy4A9tv7iCTtXSECV=CF8TM7veQOUCtCkAbgRosf7gQ@mail.gmail.com>

On Fri, Jan 31, 2014 at 6:31 AM, James Chapman <james at uplinkzero.com> wrote:
> try:
>     while self.attribute:
>         time.sleep(1)
> except KeyboardInterrupt:
>     ...
>
> My unit test could then set the attribute. However I'd still have the
> problem of how I get from the unit test line that fires up the method to the
> next line to change the attribute.

You could add a method that toggles the attribute, and use a
threading.Timer to run it after a set interval.

> if it's testable as is, how would I test it?

CPython 2.3+ can interrupt the main thread from another thread using
the built-in function `_thread.interrupt_main`:

http://docs.python.org/3/library/_thread#_thread.interrupt_main

    >>> import _thread
    >>> _thread.interrupt_main()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    KeyboardInterrupt

It's also implemented in PyPy, but not in Jython.

From james at uplinkzero.com  Fri Jan 31 14:12:56 2014
From: james at uplinkzero.com (James Chapman)
Date: Fri, 31 Jan 2014 13:12:56 +0000
Subject: [Tutor] Unit testing infinite loops
Message-ID: <CAHvkzympQeZsFWr7qFXDPrMF5wZE60d2R-TRo9=F=6tAtPSL-Q@mail.gmail.com>

Hmm...

Here is an example of how I'm currently trying to test it:

test_tutor_question.py
-----------------------------
# -*- coding: utf-8 -*-
import unittest
import mock
from tutor_question import Infinite_Loop_Tutor_Question


class Test_Infinite_Loop_Tutor_Question(unittest.TestCase):

    def test_run_forever(self):
        with mock.patch('tutor_question.Infinite_Loop_Tutor_Question.start_A')
as start_A:
            with
mock.patch('tutor_question.Infinite_Loop_Tutor_Question.start_B') as
start_B:
                inf_loop = Infinite_Loop_Tutor_Question()
                print start_A.call_count
                print start_B.call_count
                inf_loop.run_forever()
                inf_loop.interrupt_main()
                print start_A.call_count
                print start_B.call_count


if __name__ == "__main__":
    unittest.main()
-----------------------------

As you can see if you run this, the test doesn't reach the lines below
inf_loop.run_forever().

So ideally, I'd need a way of injecting a keyboard interrupt into the
method, I could then check that the exception was handled and that the
start_A and start_B calls were made.

** Obviously the print lines will be substituted for some kind of
assert lines **

FYI I'm using CPython 2.7.<something>



--
James


On 31 January 2014 12:57, eryksun <eryksun at gmail.com> wrote:
>
> On Fri, Jan 31, 2014 at 6:31 AM, James Chapman <james at uplinkzero.com> wrote:
> > try:
> >     while self.attribute:
> >         time.sleep(1)
> > except KeyboardInterrupt:
> >     ...
> >
> > My unit test could then set the attribute. However I'd still have the
> > problem of how I get from the unit test line that fires up the method to the
> > next line to change the attribute.
>
> You could add a method that toggles the attribute, and use a
> threading.Timer to run it after a set interval.
>
> > if it's testable as is, how would I test it?
>
> CPython 2.3+ can interrupt the main thread from another thread using
> the built-in function `_thread.interrupt_main`:
>
> http://docs.python.org/3/library/_thread#_thread.interrupt_main
>
>     >>> import _thread
>     >>> _thread.interrupt_main()
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in <module>
>     KeyboardInterrupt
>
> It's also implemented in PyPy, but not in Jython.

From steve at pearwood.info  Fri Jan 31 14:21:52 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 1 Feb 2014 00:21:52 +1100
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: <CAHvkzym41vLrsEVvZtFUDVEVnCmJ-nLWRZVs6td2GsTJMUU16w@mail.gmail.com>
References: <CAHvkzym41vLrsEVvZtFUDVEVnCmJ-nLWRZVs6td2GsTJMUU16w@mail.gmail.com>
Message-ID: <20140131132152.GL3799@ando>

On Fri, Jan 31, 2014 at 11:31:49AM +0000, James Chapman wrote:
> Hello tutors
> 
> I've constructed an example which shows a problem I'm having testing a real
> world program and would like to run it past you.
[...]
> class Infinite_Loop_Tutor_Question(object):
>     def run_forever(self):
>         self.start_A()
>         time.sleep(0.5)
>         self.start_B()
>         try:
>             while True:
>                 time.sleep(1)
>         except KeyboardInterrupt:
>             print("Caught Keyboard Interrupt...")
>             sys.exit(0)
[...]
> In my example above, testing the everything but the run_forever method is
> trivial.
> 
> So on to my question... The run_forever method essentially just fires up a
> bunch of threads to serve various purposes and then waits for CTRL-C to
> terminate the entire program. Testing this at the moment is very difficult
> because the unit test ends up in the infinite loop. So, would a better idea
> be to create an attribute, set it to True and then do
> 
> try:
>     while self.attribute:
>         time.sleep(1)
> except KeyboardInterrupt:
>     ...


That probably won't hurt.

 
> My unit test could then set the attribute. However I'd still have the
> problem of how I get from the unit test line that fires up the method to
> the next line to change the attribute.
> 
> So how should the run_forever method be written so that it's testable, or
> if it's testable as is, how would I test it?

What are you trying to test? You don't just "test" a method, you test 
*something specific* about the method. So what specifically are you 
trying to test?


> And please, no comments about syntax, clean exits of threads, thread
> communication, resources, or even the need for testing the run_forever
> method. In my test I want to test that it makes the relevant calls and then
> enters the infinite loop at which point I want to terminate it.

Ah, you see, now you have a problem. Consider this function:

def long_calc():
    time.sleep(60*60*24*365)
    return 1


How do I test that the function returns 1? As given, I can't 
really, not unless I wait a whole year for the sleep() to return. So 
what I can do is split the function into two pieces:

def _sleep_a_year():
    time.sleep(60*60*24*365)

def _do_calculation():
    return 1

def long_calc():
    _sleep_a_year()
    return _do_calculation()


Now I can unit-test the _do_calculation function, and long_calc() is now 
simple enough that I don't really need to unit-test it. (Unit testing 
should not be treated as a religion. You test what you can. Any testing 
is better than nothing, and if there are some parts of the program which 
are too hard to test automatically, don't test them automatically.)

Or, I can monkey-patch the time.sleep function. Before running my 
test_long_calc unit-test, I do this:

import time
time.sleep = lambda n: None

and then restore it when I'm done. But like all monkey-patching, that's 
risky -- what if the calculation relies on time.sleep somewhere else? 
(Perhaps it calls a function, which calls another function in a module 
somewhere, which calls a third module, which needs time.sleep.) So 
monkey-patching should be a last resort.

Another alternative is to write the function so it can be 
tested using a mock:

def long_calc(sleeper=time.sleep):
    sleeper(60*60*24*365)
    return 1


Then I can test it like this:

assert stupid(lambda n: None) == 1

where the lambda acts as a mock-up for the real sleep function.


Let's look at your method. As given, it's too hard to test. Maybe you 
could write a unit test which fires off another thread, which then 
sleeps for a few seconds before (somehow!) sending a KeyboardInterrupt 
to the main thread. But that's hard to explain and harder to do, and I 
really wouldn't want to rely on something so fiddly. So let's re-design 
the method with testing in mind.

First, pull out the part that does the infinite loop:

    def do_infinite_loop():
        # Loop forever. Sleep a bit to avoid hogging the CPU.
        while True:
            time.sleep(1)


That's *so simple* that it doesn't need a test. The body of the method 
is two short, easy lines, plus a comment. If somebody can read that and 
be unsure whether or not it works correctly, they're in trouble.

But, if you like, you can make it more complicated. Have the method 
check for a magic global variable, or a instance attribute, or 
something:

    def do_infinite_loop():
        # Loop forever. Sleep a bit to avoid hogging the CPU.
        # Perhaps not forever.
        if hasattr(self, 'DONT_LOOP_FOREVER'):
            x = 10
            while x > 0:
                time.sleep(1)
                x -= 1
        else:
            while True:
                time.sleep(1)


Yuck. Now you have added enough complication that it is no longer 
obvious that the method works, and while you can test the non-infinite 
loop part, you still can't test the infinite loop part. No, better to 
stick with the simplest thing that works.

Now for the rest of your method:


    def run_forever(self):
        self.start_A()
        time.sleep(0.5)
        self.start_B()
        try:
            self.do_infinite_loop()
        except KeyboardInterrupt:
            print("Caught Keyboard Interrupt...")
            sys.exit(0)


How does this help us with testing? We can monkey-patch the 
do_infinite_loop method!


class MyTest(unittest.TestCase):
    def test_run_forever_catches_KeyboardInterrupt_and_exits(self):
        def mock_looper(self):
            raise KeyboardInterrupt
        instance = Infinite_Loop_Tutor_Question()
        # Monkey-patch.
        instance.do_infinite_loop = mock_looper
        self.assertRaises(SystemExit, instance.do_infinite_loop)


Testing that it prints the appropriate message, I leave as an exercise. 
(Hint: you can re-direct stdout, run the method inside a try...except 
block, then restore stdout.)

(By the way, I haven't tested any of this code.)


-- 
Steven

From james at uplinkzero.com  Fri Jan 31 15:03:13 2014
From: james at uplinkzero.com (James Chapman)
Date: Fri, 31 Jan 2014 14:03:13 +0000
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: <20140131132152.GL3799@ando>
References: <CAHvkzym41vLrsEVvZtFUDVEVnCmJ-nLWRZVs6td2GsTJMUU16w@mail.gmail.com>
 <20140131132152.GL3799@ando>
Message-ID: <CAHvkzy=O--ejCCBCYGJZsbcS5AkbmXrhRNCcnhp25ykZxAAKRQ@mail.gmail.com>

Thanks Steven!

You've raised a few valid points, mostly that the run_forever method
should be broken up. I like the principle of a method doing just one
thing and for whatever reason I didn't apply that thinking to this
method as it's the master loop (even though it does nothing). So for
starters I'll fix that. Breaking everything up makes testing easier,
which in turn makes development easier.

On the note of what doesn't need a test...
The question of coverage always comes up when unit testing is
mentioned and I read an interesting blog article once about it. It
basically said: Assume you have 85% coverage on a program that
consists of 1,000 lines. That's 150 lines which are not tested. If
those lines are print lines, sleep lines, getters etc it's not really
a problem. But what happens when you scale that up. 1,000,000 lines of
code lets say (not unheard of, although in python that would be out of
this world big). You now end up with 150,000 lines of untested code.
While the percentage of code covered is high, there is _a_lot_ of code
there that isn't tested and a lot of room for mistakes to creep in. A
mistake on one of those 150,000 lines could break the build and
possibly cost you hours or even days tracking it down. If those lines
were tested however, your continuous integration build system would
hopefully highlight the fault.

In my experience testing works, saves time down the line, and makes
code easier to come back to.
--
James


On 31 January 2014 13:21, Steven D'Aprano <steve at pearwood.info> wrote:
> On Fri, Jan 31, 2014 at 11:31:49AM +0000, James Chapman wrote:
>> Hello tutors
>>
>> I've constructed an example which shows a problem I'm having testing a real
>> world program and would like to run it past you.
> [...]
>> class Infinite_Loop_Tutor_Question(object):
>>     def run_forever(self):
>>         self.start_A()
>>         time.sleep(0.5)
>>         self.start_B()
>>         try:
>>             while True:
>>                 time.sleep(1)
>>         except KeyboardInterrupt:
>>             print("Caught Keyboard Interrupt...")
>>             sys.exit(0)
> [...]
>> In my example above, testing the everything but the run_forever method is
>> trivial.
>>
>> So on to my question... The run_forever method essentially just fires up a
>> bunch of threads to serve various purposes and then waits for CTRL-C to
>> terminate the entire program. Testing this at the moment is very difficult
>> because the unit test ends up in the infinite loop. So, would a better idea
>> be to create an attribute, set it to True and then do
>>
>> try:
>>     while self.attribute:
>>         time.sleep(1)
>> except KeyboardInterrupt:
>>     ...
>
>
> That probably won't hurt.
>
>
>> My unit test could then set the attribute. However I'd still have the
>> problem of how I get from the unit test line that fires up the method to
>> the next line to change the attribute.
>>
>> So how should the run_forever method be written so that it's testable, or
>> if it's testable as is, how would I test it?
>
> What are you trying to test? You don't just "test" a method, you test
> *something specific* about the method. So what specifically are you
> trying to test?
>
>
>> And please, no comments about syntax, clean exits of threads, thread
>> communication, resources, or even the need for testing the run_forever
>> method. In my test I want to test that it makes the relevant calls and then
>> enters the infinite loop at which point I want to terminate it.
>
> Ah, you see, now you have a problem. Consider this function:
>
> def long_calc():
>     time.sleep(60*60*24*365)
>     return 1
>
>
> How do I test that the function returns 1? As given, I can't
> really, not unless I wait a whole year for the sleep() to return. So
> what I can do is split the function into two pieces:
>
> def _sleep_a_year():
>     time.sleep(60*60*24*365)
>
> def _do_calculation():
>     return 1
>
> def long_calc():
>     _sleep_a_year()
>     return _do_calculation()
>
>
> Now I can unit-test the _do_calculation function, and long_calc() is now
> simple enough that I don't really need to unit-test it. (Unit testing
> should not be treated as a religion. You test what you can. Any testing
> is better than nothing, and if there are some parts of the program which
> are too hard to test automatically, don't test them automatically.)
>
> Or, I can monkey-patch the time.sleep function. Before running my
> test_long_calc unit-test, I do this:
>
> import time
> time.sleep = lambda n: None
>
> and then restore it when I'm done. But like all monkey-patching, that's
> risky -- what if the calculation relies on time.sleep somewhere else?
> (Perhaps it calls a function, which calls another function in a module
> somewhere, which calls a third module, which needs time.sleep.) So
> monkey-patching should be a last resort.
>
> Another alternative is to write the function so it can be
> tested using a mock:
>
> def long_calc(sleeper=time.sleep):
>     sleeper(60*60*24*365)
>     return 1
>
>
> Then I can test it like this:
>
> assert stupid(lambda n: None) == 1
>
> where the lambda acts as a mock-up for the real sleep function.
>
>
> Let's look at your method. As given, it's too hard to test. Maybe you
> could write a unit test which fires off another thread, which then
> sleeps for a few seconds before (somehow!) sending a KeyboardInterrupt
> to the main thread. But that's hard to explain and harder to do, and I
> really wouldn't want to rely on something so fiddly. So let's re-design
> the method with testing in mind.
>
> First, pull out the part that does the infinite loop:
>
>     def do_infinite_loop():
>         # Loop forever. Sleep a bit to avoid hogging the CPU.
>         while True:
>             time.sleep(1)
>
>
> That's *so simple* that it doesn't need a test. The body of the method
> is two short, easy lines, plus a comment. If somebody can read that and
> be unsure whether or not it works correctly, they're in trouble.
>
> But, if you like, you can make it more complicated. Have the method
> check for a magic global variable, or a instance attribute, or
> something:
>
>     def do_infinite_loop():
>         # Loop forever. Sleep a bit to avoid hogging the CPU.
>         # Perhaps not forever.
>         if hasattr(self, 'DONT_LOOP_FOREVER'):
>             x = 10
>             while x > 0:
>                 time.sleep(1)
>                 x -= 1
>         else:
>             while True:
>                 time.sleep(1)
>
>
> Yuck. Now you have added enough complication that it is no longer
> obvious that the method works, and while you can test the non-infinite
> loop part, you still can't test the infinite loop part. No, better to
> stick with the simplest thing that works.
>
> Now for the rest of your method:
>
>
>     def run_forever(self):
>         self.start_A()
>         time.sleep(0.5)
>         self.start_B()
>         try:
>             self.do_infinite_loop()
>         except KeyboardInterrupt:
>             print("Caught Keyboard Interrupt...")
>             sys.exit(0)
>
>
> How does this help us with testing? We can monkey-patch the
> do_infinite_loop method!
>
>
> class MyTest(unittest.TestCase):
>     def test_run_forever_catches_KeyboardInterrupt_and_exits(self):
>         def mock_looper(self):
>             raise KeyboardInterrupt
>         instance = Infinite_Loop_Tutor_Question()
>         # Monkey-patch.
>         instance.do_infinite_loop = mock_looper
>         self.assertRaises(SystemExit, instance.do_infinite_loop)
>
>
> Testing that it prints the appropriate message, I leave as an exercise.
> (Hint: you can re-direct stdout, run the method inside a try...except
> block, then restore stdout.)
>
> (By the way, I haven't tested any of this code.)
>
>
> --
> Steven
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From steve at pearwood.info  Fri Jan 31 15:20:48 2014
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 1 Feb 2014 01:20:48 +1100
Subject: [Tutor] Unit testing infinite loops
In-Reply-To: <CAHvkzy=O--ejCCBCYGJZsbcS5AkbmXrhRNCcnhp25ykZxAAKRQ@mail.gmail.com>
References: <CAHvkzym41vLrsEVvZtFUDVEVnCmJ-nLWRZVs6td2GsTJMUU16w@mail.gmail.com>
 <20140131132152.GL3799@ando>
 <CAHvkzy=O--ejCCBCYGJZsbcS5AkbmXrhRNCcnhp25ykZxAAKRQ@mail.gmail.com>
Message-ID: <20140131142048.GM3799@ando>

On Fri, Jan 31, 2014 at 02:03:13PM +0000, James Chapman wrote:

> On the note of what doesn't need a test...
> The question of coverage always comes up when unit testing is
> mentioned and I read an interesting blog article once about it. It
> basically said: Assume you have 85% coverage on a program that
> consists of 1,000 lines. That's 150 lines which are not tested. If
> those lines are print lines, sleep lines, getters etc it's not really
> a problem. But what happens when you scale that up. 1,000,000 lines of
> code lets say (not unheard of, although in python that would be out of
> this world big). You now end up with 150,000 lines of untested code.
> While the percentage of code covered is high, there is _a_lot_ of code
> there that isn't tested and a lot of room for mistakes to creep in. A
> mistake on one of those 150,000 lines could break the build and
> possibly cost you hours or even days tracking it down. 

Or weeks, or months... 

You're right of course. But look at it this way. How much time, effort, 
money, and lost opportunities to be doing other things, are you willing 
to spend to asymptotically approach 100% coverage? It might take a week 
of development writing nothing but tests to get to 80% coverage, another 
week to get to 85%, a further week to get to 87%, another week again to 
get to 88%... 

At some point you say, "I have better things to do." Or your customers 
start questioning why the bills keep coming but the features aren't 
being delivered. (Customers want features, not tests.)

I'm not trying to talk you out of testing this. I agree completely with 
this:

> If those lines
> were tested however, your continuous integration build system would
> hopefully highlight the fault.
> 
> In my experience testing works, saves time down the line, and makes
> code easier to come back to.


but life is short, and even if you like writing tests, there comes a 
point of diminishing returns. And the ideal of programming is to write 
code which is obviously correct (as opposed to code which merely 
contains no obvious bugs).

And of course: better 85% coverage than 50%. Better 50% coverage 
than 10%. Better 10% coverage than no tests at all.


-- 
Steven

From shahmed at sfwmd.gov  Fri Jan 31 17:20:57 2014
From: shahmed at sfwmd.gov (Ahmed, Shakir)
Date: Fri, 31 Jan 2014 16:20:57 +0000
Subject: [Tutor] run a python script from access form
Message-ID: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>

Hi,

I am trying to run a python script from Microsoft Access form.  Your help is highly appreciated.

Thanks
S


We value your opinion. Please take a few minutes to share your comments on the service you received from the District by clicking on this link<http://my.sfwmd.gov/portal/page/portal/pg_grp_surveysystem/survey%20ext?pid=1653>.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140131/dbd00e55/attachment.html>

From joel.goldstick at gmail.com  Fri Jan 31 18:19:47 2014
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Fri, 31 Jan 2014 12:19:47 -0500
Subject: [Tutor] run a python script from access form
In-Reply-To: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
Message-ID: <CAPM-O+yGFBwhgGp=dMpscv+TmZXQ0-0eNzM0=p-sLNw4LxMCOA@mail.gmail.com>

Look up shell function
On Jan 31, 2014 11:37 AM, "Ahmed, Shakir" <shahmed at sfwmd.gov> wrote:

>  Hi,
>
>
>
> I am trying to run a python script from Microsoft Access form.  Your help
> is highly appreciated.
>
>
>
> Thanks
>
> S
>
>
> We value your opinion. Please take a few minutes to share your comments on
> the service you received from the District by clicking on this link<http://my.sfwmd.gov/portal/page/portal/pg_grp_surveysystem/survey%20ext?pid=1653>.
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140131/331b1667/attachment-0001.html>

From emile at fenx.com  Fri Jan 31 18:26:01 2014
From: emile at fenx.com (emile)
Date: Fri, 31 Jan 2014 09:26:01 -0800
Subject: [Tutor] run a python script from access form
In-Reply-To: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
Message-ID: <lcgmav$393$1@ger.gmane.org>

On 01/31/2014 08:20 AM, Ahmed, Shakir wrote:
> Hi,
>
> I am trying to run a python script from Microsoft Access form.  Your help is highly appreciated.

I've not done this with Access, but I have created com servers in python 
that were used from Excel.  I'd start with ActiveState's python 
distribution which includes Mark Hammond's windows extensions.  Then 
read through the docs on com servers.  It's been a while since I've done 
so, but I expect that should get you going.

Emile




From gb.gabrielebrambilla at gmail.com  Fri Jan 31 16:08:01 2014
From: gb.gabrielebrambilla at gmail.com (Gabriele Brambilla)
Date: Fri, 31 Jan 2014 10:08:01 -0500
Subject: [Tutor] interactive script
Message-ID: <CABmgkicg20T5m4QV__RPonfU_ZTsNzrTzuXU+eaUmf0C=ZVSbQ@mail.gmail.com>

Hi,
I'm very new to Python (just 5 days!)
is there a possibility to write an interactive script?
in the sense that:

- you run your script and it do some things that you don't want to type
everytime you run the program
- but at a certain step I want that it ask me question like "which column
of this matrix do you want to use?" and I want to give to it the answer,
and after it that it do what I answered.
- I don't want to use argv method.

thank you

Gabriele

p.s: I'm using Anaconda
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140131/297b3ae3/attachment.html>

From gb.gabrielebrambilla at gmail.com  Fri Jan 31 16:38:50 2014
From: gb.gabrielebrambilla at gmail.com (Gabriele Brambilla)
Date: Fri, 31 Jan 2014 10:38:50 -0500
Subject: [Tutor] interactive script
In-Reply-To: <CABmgkicg20T5m4QV__RPonfU_ZTsNzrTzuXU+eaUmf0C=ZVSbQ@mail.gmail.com>
References: <CABmgkicg20T5m4QV__RPonfU_ZTsNzrTzuXU+eaUmf0C=ZVSbQ@mail.gmail.com>
Message-ID: <CABmgkifWgcte1YLoAXr+He3Pbo_yjzjbw4MQ9+9BQG2J7+BWJA@mail.gmail.com>

to simplify the question:
does a command like cin in C++ or scanf in C exist??

thanks

Gabriele


2014-01-31 Gabriele Brambilla <gb.gabrielebrambilla at gmail.com>:

> Hi,
> I'm very new to Python (just 5 days!)
> is there a possibility to write an interactive script?
> in the sense that:
>
> - you run your script and it do some things that you don't want to type
> everytime you run the program
> - but at a certain step I want that it ask me question like "which column
> of this matrix do you want to use?" and I want to give to it the answer,
> and after it that it do what I answered.
> - I don't want to use argv method.
>
> thank you
>
> Gabriele
>
> p.s: I'm using Anaconda
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140131/d31c533c/attachment.html>

From duxbuz at hotmail.com  Fri Jan 31 10:13:30 2014
From: duxbuz at hotmail.com (Ian D)
Date: Fri, 31 Jan 2014 09:13:30 +0000
Subject: [Tutor] auto completion before initially running program
Message-ID: <DUB123-W2340B77FBA873E41C16A18CBAE0@phx.gbl>

I notice that until a program has been run once, and I presume loaded its imports, I cannot use auto completion.
 
I don't suppose there is a way to have it load modules in a way that would give me access to the module functions straight away other than running the program
 
I presume there is no way around this.
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140131/b52dc4b9/attachment.html>

From duxbuz at hotmail.com  Fri Jan 31 10:57:00 2014
From: duxbuz at hotmail.com (Ian D)
Date: Fri, 31 Jan 2014 09:57:00 +0000
Subject: [Tutor] is an alias a variable
Message-ID: <DUB123-W1A247BED8AD3C5D70FB8ECBAE0@phx.gbl>

Hi
 
is 
import longModuleName  as lmn
 
or 
 
lmn = longModuleName
 
creating an alias or assigning to a variable..... or both?
 
Thanks
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140131/1f7d3820/attachment.html>

From duxbuz at hotmail.com  Fri Jan 31 11:09:12 2014
From: duxbuz at hotmail.com (Ian D)
Date: Fri, 31 Jan 2014 10:09:12 +0000
Subject: [Tutor] creating Turtle() object using 2 different ways
Message-ID: <DUB123-W3730A1C44DFD9E56E11C01CBAE0@phx.gbl>

Hi
 
Another quickie.
 
I can create turtle objects (if that's the correct terminology) using 2 different ways, both work.
 
t1 = turtle.Turtle()
 or
t2 = turtle
 
But which is the best practice... and why?
 
 
 
 
import turtle
 
t1 = turtle.Turtle()
 
t2 = turtle
 
t1.fd(100)
 
t2.goto(-100,100)
t2.fd(100)
 
 
 
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140131/3133537e/attachment.html>

From breamoreboy at yahoo.co.uk  Fri Jan 31 21:32:26 2014
From: breamoreboy at yahoo.co.uk (Mark Lawrence)
Date: Fri, 31 Jan 2014 20:32:26 +0000
Subject: [Tutor] interactive script
In-Reply-To: <CABmgkifWgcte1YLoAXr+He3Pbo_yjzjbw4MQ9+9BQG2J7+BWJA@mail.gmail.com>
References: <CABmgkicg20T5m4QV__RPonfU_ZTsNzrTzuXU+eaUmf0C=ZVSbQ@mail.gmail.com>
 <CABmgkifWgcte1YLoAXr+He3Pbo_yjzjbw4MQ9+9BQG2J7+BWJA@mail.gmail.com>
Message-ID: <lch17o$702$1@ger.gmane.org>

On 31/01/2014 15:38, Gabriele Brambilla wrote:

Please don't top post on this mailing list.

> to simplify the question:
> does a command like cin in C++ or scanf in C exist??
>
> thanks
>
> Gabriele
>
>
> 2014-01-31 Gabriele Brambilla <gb.gabrielebrambilla at gmail.com
> <mailto:gb.gabrielebrambilla at gmail.com>>:
>
>     Hi,
>     I'm very new to Python (just 5 days!)
>     is there a possibility to write an interactive script?
>     in the sense that:
>
>     - you run your script and it do some things that you don't want to
>     type everytime you run the program
>     - but at a certain step I want that it ask me question like "which
>     column of this matrix do you want to use?" and I want to give to it
>     the answer, and after it that it do what I answered.
>     - I don't want to use argv method.
>
>     thank you
>
>     Gabriele
>
>     p.s: I'm using Anaconda
>

Use raw_input() with Python 2 or input() with Python 3.

-- 
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  Fri Jan 31 21:32:58 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 31 Jan 2014 20:32:58 +0000
Subject: [Tutor] interactive script
In-Reply-To: <CABmgkicg20T5m4QV__RPonfU_ZTsNzrTzuXU+eaUmf0C=ZVSbQ@mail.gmail.com>
References: <CABmgkicg20T5m4QV__RPonfU_ZTsNzrTzuXU+eaUmf0C=ZVSbQ@mail.gmail.com>
Message-ID: <lch19e$7ck$1@ger.gmane.org>

On 31/01/14 15:08, Gabriele Brambilla wrote:
> Hi,
> I'm very new to Python (just 5 days!)
> is there a possibility to write an interactive script?

Yes,
If using Python v3 use input()

If using Python v2 use raw_input() (and definitely not input() )

You'll get a string back so may need to convert
it to int() or float() or whatever.

If you really insist on reading multiple values in
a single line of input look at str.split() or
for scanf style handling try the struct module,
although it's not really intended for user input...

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From emile at fenx.com  Fri Jan 31 21:37:29 2014
From: emile at fenx.com (emile)
Date: Fri, 31 Jan 2014 12:37:29 -0800
Subject: [Tutor] auto completion before initially running program
In-Reply-To: <DUB123-W2340B77FBA873E41C16A18CBAE0@phx.gbl>
References: <DUB123-W2340B77FBA873E41C16A18CBAE0@phx.gbl>
Message-ID: <lch1hu$7gq$1@ger.gmane.org>

On 01/31/2014 01:13 AM, Ian D wrote:
> I notice that until a program has been run once, and I presume loaded its imports, I cannot use auto completion.
>
> I don't suppose there is a way to have it load modules in a way that would give me access to the module functions straight away other than running the program
>
> I presume there is no way around this.

Autocompletion is provided by the editor you're using.  You'll need to 
place some more context around this question to get appropriate responses.

Emile




From alan.gauld at btinternet.com  Fri Jan 31 21:35:36 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 31 Jan 2014 20:35:36 +0000
Subject: [Tutor] run a python script from access form
In-Reply-To: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
References: <554ED400F994BF43AD3E6ED0328200BA7ABEFD2F@whqembx03p.ad.sfwmd.gov>
Message-ID: <lch1eb$7ck$2@ger.gmane.org>

On 31/01/14 16:20, Ahmed, Shakir wrote:
> Hi,
>
> I am trying to run a python script from Microsoft Access form.  Your
> help is highly appreciated.

If its just a command line tool then do it the same way you'd
run a .bat file or another exe.

If you want to interact with the script as it runs then you might
want to look at using COM via ctypes or the pythonwin extensions.
But that assumes you are creatig the script and its not one
that already exists...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From emile at fenx.com  Fri Jan 31 21:41:02 2014
From: emile at fenx.com (emile)
Date: Fri, 31 Jan 2014 12:41:02 -0800
Subject: [Tutor] is an alias a variable
In-Reply-To: <DUB123-W1A247BED8AD3C5D70FB8ECBAE0@phx.gbl>
References: <DUB123-W1A247BED8AD3C5D70FB8ECBAE0@phx.gbl>
Message-ID: <lch1om$crn$1@ger.gmane.org>

On 01/31/2014 01:57 AM, Ian D wrote:
> Hi
>
> is
> import longModuleName  as lmn
>
> or
>
> lmn = longModuleName
>
> creating an alias or assigning to a variable..... or both?

Yes (I'm not goint to get into the symantic issues of what's an alias or 
variable)

Python 2.7.3 (default, Nov  2 2012, 09:35:42)
[GCC 2.96 20000731 (Red Hat Linux 7.1 2.96-85)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
 >>> import sys as s
 >>> m = s
 >>> id(m)
1075446500
 >>> id(s)
1075446500
 >>>

The id's are the same so they refer to the same object.

Emile




From alan.gauld at btinternet.com  Fri Jan 31 22:36:13 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 31 Jan 2014 21:36:13 +0000
Subject: [Tutor] is an alias a variable
In-Reply-To: <DUB123-W1A247BED8AD3C5D70FB8ECBAE0@phx.gbl>
References: <DUB123-W1A247BED8AD3C5D70FB8ECBAE0@phx.gbl>
Message-ID: <lch500$gae$1@ger.gmane.org>

On 31/01/14 09:57, Ian D wrote:

> import longModuleName  as lmn
>
> or
>
> lmn = longModuleName
>
> creating an alias or assigning to a variable..... or both?

variables in Python are just names.
There is no concept of an alias as such, its just another
name referring to the same object.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From alan.gauld at btinternet.com  Fri Jan 31 22:38:26 2014
From: alan.gauld at btinternet.com (Alan Gauld)
Date: Fri, 31 Jan 2014 21:38:26 +0000
Subject: [Tutor] creating Turtle() object using 2 different ways
In-Reply-To: <DUB123-W3730A1C44DFD9E56E11C01CBAE0@phx.gbl>
References: <DUB123-W3730A1C44DFD9E56E11C01CBAE0@phx.gbl>
Message-ID: <lch545$gae$2@ger.gmane.org>

On 31/01/14 10:09, Ian D wrote:
> Hi
>
> Another quickie.
>
> I can create turtle objects (if that's the correct terminology) using 2
> different ways, both work.
>
> t1 = turtle.Turtle()
>   or
> t2 = turtle
>
> But which is the best practice... and why?
>
>
>
>
> import turtle
>
> t1 = turtle.Turtle()

This creates an instance of a turtle

> t2 = turtle

This is just a reference to the turtle module

> t1.fd(100)

This moves your specified instance of a turtle

> t2.goto(-100,100)
> t2.fd(100)

These move the global turtle object using the
module level functions.

If you want multiple turtles you should use
the first version.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.flickr.com/photos/alangauldphotos


From bgailer at gmail.com  Fri Jan 31 22:59:08 2014
From: bgailer at gmail.com (bob gailer)
Date: Fri, 31 Jan 2014 16:59:08 -0500
Subject: [Tutor] Code runs in interpreter but won't output to stdout
In-Reply-To: <CA+KU-OExHf=_aDYJ0x=Sqqm=cxaQdrmaqOdWE1dDu6PNpJv=eA@mail.gmail.com>
References: <CA+KU-OG3MhsgVhTRswLQsFMqY2Hz+SAAjpVo45H8OsFcReSs1w@mail.gmail.com>	<52E97F97.8080705@gmail.com>
 <CA+KU-OExHf=_aDYJ0x=Sqqm=cxaQdrmaqOdWE1dDu6PNpJv=eA@mail.gmail.com>
Message-ID: <52EC1CAC.4070202@gmail.com>

On 1/29/2014 8:59 PM, scurvy scott wrote:

Please always reply to the tutor list so we can all play with your question.

>
> On 1/28/2014 9:12 PM, scurvy scott wrote:
>
>     Hi guys, I'm trying to figure out why my code won't output to
>     terminal, but will run just fine in interpreter.
>     I'm using python 2.7.3 on Debian Linux/Crunchbang.
>
>     Here is my code.
>
>     import requests
>     from bs4 import BeautifulSoup as beautiful
>     import sys
>
>     def dogeScrape(username, password):
>         payload = {'username': username, 'password': password}
>         r = requests.post("http://dogehouse.org/index.php?page=login",
>     data=payload)
>         soup = beautiful(r.text)
>         confirmed = str(soup.findAll('span',{'class':'confirmed'}))
>         print "Confirmed account balance: " + confirmed[86:98]
>
>     dogeScrape("XXXX", "XXXX")
>
>     It will output the "confirmed....." part, just not the confirmed
>     variable. It will output the entire thing in the interpreter.
>
I am stuck at "import requests". Where did you get that module?

My guess is that you are getting a different response from the server. I 
suggest you write the entire response text to a file, then edit it 
looking for 'class="confirmed"'.

I signed up at Dogehouse. What the heck is it? There is no explanation 
as to what it does or what I'd do with it!