From steve at pearwood.info  Sun May  1 00:18:27 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 1 May 2016 14:18:27 +1000
Subject: [Tutor] META: Moderation and subscription to the tutor list
Message-ID: <20160501041826.GB13497@ando.pearwood.info>

Hi Alan,


I thought I'd mention that the list-owners of "python-list" have now 
decided to only allow people to post if they are subscribed to the list:

https://mail.python.org/pipermail/python-list/2016-April/707571.html


The motivation is to ensure that if people ask a question, and people 
reply only to the list, the original poster has at least a chance of 
seeing the replies.

Of course, in the case of python-list, non-subscribers can just use the 
Usenet interface (comp.lang.python, or Google Groups, or gmane). But 
anyone using Usenet is presumably savvy enough to check for replies 
using Usenet.

What's your policy here on the tutor list? I think we should require 
subscription before people can post. (And I think we should default to 
individual emails, not daily digest.)



-- 
Steve

From thomasolaoluwa at gmail.com  Sun May  1 00:20:23 2016
From: thomasolaoluwa at gmail.com (Olaoluwa Thomas)
Date: Sun, 1 May 2016 05:20:23 +0100
Subject: [Tutor] Issue with Code [SOLVED]
Message-ID: <CABq_6eOd_+ud2tkuECBzZ_qJ271=tBgTkM9WkXaVLiJ3TGgDTw@mail.gmail.com>

Thank you so much, Alan. That fixed it (See Script 2[SOLVED] below).

For the purpose of record-keeping, I'm pasting the entire code of all
scripts below as I should have done from the very beginning.

P.S. How were you able to open attachments with the restrictions on this
mailing list?

Script 1
hours = raw_input ('How many hours do you work?\n')
rate = raw_input ('What is your hourly rate?\n')
gross = float(hours) * float(rate)
print "Your Gross pay is "+str(round(gross, 4))

Script 2
hours = raw_input ('How many hours do you work?\n')
rate = raw_input ('What is your hourly rate?\n')
if hours > 40:
    gross = ((float(hours) - 40) * (float(rate) * 1.5)) + (40 * float(rate))
elif hours >= 0 and hours <= 40:
    gross = float(hours) * float(rate)
print "Your Gross pay is "+str(round(gross, 4))

Script 2 [SOLVED]
hours = float(raw_input ('How many hours do you work?\n'))
rate = float(raw_input ('What is your hourly rate?\n'))
if hours > 40:
    gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
elif hours >= 0 and hours <= 40:
    gross = hours * rate
print "Your Gross pay is "+str(round(gross, 4))

I'm gonna add Try and Except to make it more responsive.

Thanks a lot!

*Warm regards,*

*Olaoluwa O. Thomas,*
*+2347068392705*

On Sun, May 1, 2016 at 2:00 AM, Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 01/05/16 01:16, Alan Gauld via Tutor wrote:
>
> > I can't see anything obviously wrong in your code
>
> I was too busy focusing on the calculations that
> I didn't check the 'if' test closely enough.
> You need to convert your values from strings
> before comparing them.
>
> hours = float(raw_input ('How many hours do you work?\n'))
> rate = float(raw_input ('What is your hourly rate?\n'))
> if hours > 40:
>    gross = (hours-40)*(rate*1.5) + (rate*40)
> else:
>    gross = hours*rate
>
>
> Sorry,
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From robertvstepp at gmail.com  Sun May  1 02:02:50 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 1 May 2016 01:02:50 -0500
Subject: [Tutor] int(1.99...99) = 1 and can = 2
Message-ID: <CANDiX9KD3Jz+3FKFYDrSepXgo11FVM6ZAZrJAzc_QZ1ceRMOoA@mail.gmail.com>

Life has kept me from Python studies since March, but now I resume.
Playing around in the interpreter I tried:

py3: 1.9999999999999999
2.0
py3: 1.999999999999999
1.999999999999999
py3: int(1.9999999999999999)
2
py3: int(1.999999999999999)
1

It has been many years since I did problems in converting decimal to
binary representation (Shades of two's-complement!), but I am under
the (apparently mistaken!) impression that in these 0.999...999
situations that the floating point representation should not go "up"
in value to the next integer representation.  This is acting like in
the case of 15 nines the final bit is "0", but with 16 nines it is
"1".  Would someone clarify this for me, please?

-- 
boB

From cs at zip.com.au  Sun May  1 01:35:46 2016
From: cs at zip.com.au (cs at zip.com.au)
Date: Sun, 1 May 2016 15:35:46 +1000
Subject: [Tutor] META: Moderation and subscription to the tutor list
In-Reply-To: <20160501041826.GB13497@ando.pearwood.info>
References: <20160501041826.GB13497@ando.pearwood.info>
Message-ID: <20160501053546.GA3946@cskk.homeip.net>

On 01May2016 14:18, Steven D'Aprano <steve at pearwood.info> wrote:
>Hi Alan,
>
>I thought I'd mention that the list-owners of "python-list" have now
>decided to only allow people to post if they are subscribed to the list:
>
>https://mail.python.org/pipermail/python-list/2016-April/707571.html
>
>The motivation is to ensure that if people ask a question, and people
>reply only to the list, the original poster has at least a chance of
>seeing the replies.
>
>Of course, in the case of python-list, non-subscribers can just use the
>Usenet interface (comp.lang.python, or Google Groups, or gmane). But
>anyone using Usenet is presumably savvy enough to check for replies
>using Usenet.
>
>What's your policy here on the tutor list? I think we should require
>subscription before people can post. (And I think we should default to
>individual emails, not daily digest.)

I am not Alan, but personally I am +0.8 and +1 on these.

I think requiring subscription ensures that users see responses. I don't know 
if tutor is already like that, and requiring subscription _does_ raise the bar 
for people coming for help. I would hope that any "please subscribe in order to 
post" list responses to newcomers was both welcoming and very clear on how to 
do it.

There seems to me a subjectly large number of very short threads with a 
question from someone, a couple of responses from list members, and no further 
reply.

To me this argues that either newcomers are not subscribed and probably do not 
see any responses, or that sufficient are discourteous enough or naive enough 
to nothing bother to acknowledge help.

Finally, I would like to see digest simply not offered. They are a disaster.  
They break subject lines, threading and bury responses in noise.

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

From robertvstepp at gmail.com  Sun May  1 02:23:40 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 1 May 2016 01:23:40 -0500
Subject: [Tutor] META: Moderation and subscription to the tutor list
In-Reply-To: <20160501053546.GA3946@cskk.homeip.net>
References: <20160501041826.GB13497@ando.pearwood.info>
 <20160501053546.GA3946@cskk.homeip.net>
Message-ID: <CANDiX9Kn+NYP2N3S5YszHY87qJM64Y=ENh9ZS=Ah29=ik=2X=w@mail.gmail.com>

On Sun, May 1, 2016 at 12:35 AM,  <cs at zip.com.au> wrote:
> On 01May2016 14:18, Steven D'Aprano <steve at pearwood.info> wrote:
>>
>> Hi Alan,
>>
>> I thought I'd mention that the list-owners of "python-list" have now
>> decided to only allow people to post if they are subscribed to the list:
>>
>> https://mail.python.org/pipermail/python-list/2016-April/707571.html
>>
>> The motivation is to ensure that if people ask a question, and people
>> reply only to the list, the original poster has at least a chance of
>> seeing the replies.
>>
>> Of course, in the case of python-list, non-subscribers can just use the
>> Usenet interface (comp.lang.python, or Google Groups, or gmane). But
>> anyone using Usenet is presumably savvy enough to check for replies
>> using Usenet.
>>
>> What's your policy here on the tutor list? I think we should require
>> subscription before people can post. (And I think we should default to
>> individual emails, not daily digest.)
>
>
> I am not Alan, but personally I am +0.8 and +1 on these.
>
> I think requiring subscription ensures that users see responses. I don't
> know if tutor is already like that, and requiring subscription _does_ raise
> the bar for people coming for help. I would hope that any "please subscribe
> in order to post" list responses to newcomers was both welcoming and very
> clear on how to do it.

I am in agreement with this as well.  I have often wondered if
newcomers are subscribed or not as after subscription one receives a
very helpful email which addresses most of the common post formatting
issues that we seem to endlessly rehash.  Or perhaps I am one of the
few who actually read it upon subscribing?

I wonder no matter which way the current matter gets decided, if it
might be time to rewrite the automated response email.  I just got one
(again) after sending a different post and looking it over, it is
overly long and wordy, perhaps discouraging newcomers from actually
reading it?  Also, I note that the verboten "top posting" is never
mentioned.  It probably should be added.  I feel that the interleaved
writing style employed by many lists is completely foreign to
newcomers to programming.

> There seems to me a subjectly large number of very short threads with a
> question from someone, a couple of responses from list members, and no
> further reply.

> Finally, I would like to see digest simply not offered. They are a disaster.
> They break subject lines, threading and bury responses in noise.

+ infinity!

-- 
boB

From eryksun at gmail.com  Sun May  1 04:06:09 2016
From: eryksun at gmail.com (eryk sun)
Date: Sun, 1 May 2016 03:06:09 -0500
Subject: [Tutor] int(1.99...99) = 1 and can = 2
In-Reply-To: <CANDiX9KD3Jz+3FKFYDrSepXgo11FVM6ZAZrJAzc_QZ1ceRMOoA@mail.gmail.com>
References: <CANDiX9KD3Jz+3FKFYDrSepXgo11FVM6ZAZrJAzc_QZ1ceRMOoA@mail.gmail.com>
Message-ID: <CACL+1asn3Zst4w0NjrmuhkFRxBtKMK=185JkSauVXMXGEtRyDg@mail.gmail.com>

On Sun, May 1, 2016 at 1:02 AM, boB Stepp <robertvstepp at gmail.com> wrote:
>
> py3: 1.9999999999999999
> 2.0
> py3: 1.999999999999999
> 1.999999999999999
...
> It has been many years since I did problems in converting decimal to
> binary representation (Shades of two's-complement!), but I am under
> the (apparently mistaken!) impression that in these 0.999...999
> situations that the floating point representation should not go "up"
> in value to the next integer representation.

https://en.wikipedia.org/wiki/Double-precision_floating-point_format

A binary64 float has 52 signifcand bits, with an implicit integer
value of 1, so it's effectively 53 bits. That leaves 11 bits for the
exponent, and 1 bit for the sign.

The 11-bit exponent value is biased by 1023, i.e. 2**0 is stored as
1023. The minimum binary exponent is (1-1023) == -1022, and the
maximum binary exponent is (2046-1023) == 1023. A biased exponent of 0
signifies either signed 0 (mantissa is zero) or a subnormal number
(mantissa is nonzero). A biased exponent of 2047 signifies either
signed infinity (mantissa is zero) or a non-number, i.e. NaN
(mantissia is nonzero).

The largest finite value has all 53 bits set:

    >>> sys.float_info.max
    1.7976931348623157e+308

    >>> sum(Decimal(2**-n) for n in range(53)) * 2**1023
    Decimal('1.797693134862315708145274237E+308')

The smallest finite value has the 52 fractional bits unset:

    >>> sys.float_info.min
    2.2250738585072014e-308

    >>> Decimal(2)**-1022
    Decimal('2.225073858507201383090232717E-308')

The machine epsilon value is 2**-52:

    >>> sys.float_info.epsilon
    2.220446049250313e-16

    >>> Decimal(2)**-52
    Decimal('2.220446049250313080847263336E-16')

Your number is just shy of 2, i.e. implicit 1 plus a 52-bit fractional
value and a binary exponent of 0.

    >>> sum(Decimal(2**-n) for n in range(53))
    Decimal('1.999999999999999777955395075')

The next increment by epsilon jumps to 2.0. The 52-bit mantissa rolls
over to all 0s, and the exponent increments by 1, i.e. (1 + 0.0) *
2**1. Python's float type has a hex() method to let you inspect this:

    >>> (1.9999999999999998).hex()
    '0x1.fffffffffffffp+0'
    >>> (2.0).hex()
    '0x1.0000000000000p+1'

where the integer part is 0x1; the 52-bit mantissa is 13 hexadecimal
digits; and the binary exponent comes after 'p'. You can also parse a
float hex string using float.fromhex():

    >>> float.fromhex('0x1.0000000000000p-1022')
    2.2250738585072014e-308

    >>> float.fromhex('0x1.fffffffffffffp+1023')
    1.7976931348623157e+308

From alan.gauld at yahoo.co.uk  Sun May  1 04:47:34 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 1 May 2016 09:47:34 +0100
Subject: [Tutor] Issue with Code [SOLVED]
In-Reply-To: <CABq_6eOd_+ud2tkuECBzZ_qJ271=tBgTkM9WkXaVLiJ3TGgDTw@mail.gmail.com>
References: <CABq_6eOd_+ud2tkuECBzZ_qJ271=tBgTkM9WkXaVLiJ3TGgDTw@mail.gmail.com>
Message-ID: <ng4fr6$g9r$1@ger.gmane.org>

On 01/05/16 05:20, Olaoluwa Thomas wrote:
> Thank you so much, Alan. That fixed it (See Script 2[SOLVED] below).
> 
> For the purpose of record-keeping, I'm pasting the entire code of all
> scripts below as I should have done from the very beginning.
> 

thanks :-)

> P.S. How were you able to open attachments with the restrictions on this
> mailing list?

The two code attachments made it to my reader.
But that seems to be a fairly arbitrary occurence.
The screen shot didn't make it.

Some make it, others don't. I don't know the exact
set of rules that determine when an attachment
gets through!

> Script 2 [SOLVED]
> hours = float(raw_input ('How many hours do you work?\n'))
> rate = float(raw_input ('What is your hourly rate?\n'))
> if hours > 40:
>     gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
> elif hours >= 0 and hours <= 40:
>     gross = hours * rate
> print "Your Gross pay is "+str(round(gross, 4))

You could have left it as else rather than elif,
but otherwise that's fine.

> I'm gonna add Try and Except to make it more responsive.

I'm not sure what you mean by responsive? The only
place try/except could/should be applied is round
the float conversions. But it only makes sense if
you put them inside a loop so you can force the
user to try again if the input is invalid.

Something like:

while True:
   try:
     value = float(input(...))
     break
   except ValueError:
     print 'warning message....'
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos



From ben+python at benfinney.id.au  Sun May  1 04:47:41 2016
From: ben+python at benfinney.id.au (Ben Finney)
Date: Sun, 01 May 2016 18:47:41 +1000
Subject: [Tutor] Python Homework
References: <CA+KwKjp6XH1Ue4y9WVb0a7GqXJURgzD+haJZckF8WLFYBH4+hA@mail.gmail.com>
Message-ID: <85zisago5u.fsf@benfinney.id.au>

Katie Tuite <katuite13 at gmail.com> writes:

> I'm trying to do a python homework question and cannot figure out how
> to start at all.

You'll need to help us more than that :-)

What is the confusion you have? What do you understand so far? Can you
re-phrase the question in your words, so we can get some insight into
what may be lacking in your understanding?

> This is the question

You'll need to write only plain text email (no attached documents, no
?rich text?) for the information to survive correctly. This is always
good practice for any technical discussion forum.

-- 
 \       ?The best in us does not require the worst in us: Our love of |
  `\     other human beings does not need to be nurtured by delusion.? |
_o__)                             ?Sam Harris, at _Beyond Belief 2006_ |
Ben Finney


From alan.gauld at yahoo.co.uk  Sun May  1 05:06:42 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 1 May 2016 10:06:42 +0100
Subject: [Tutor] META: Moderation and subscription to the tutor list
In-Reply-To: <20160501041826.GB13497@ando.pearwood.info>
References: <20160501041826.GB13497@ando.pearwood.info>
Message-ID: <ng4gv1$vru$1@ger.gmane.org>

On 01/05/16 05:18, Steven D'Aprano wrote:

> What's your policy here on the tutor list? 

I don't really have a policy. The list policy, set by
my predecessors, is to allow anyone to send mail and
encourage them to subscribe. All unsubscribed mail
goes to moderation (and there is not very much of it).

New subscribers are automatically put on moderation.
They are manually removed from moderation when they
post often enough that I recognize their ID and have
enough time/energy to visit the members page...

Replies can be seen by non subscribers in several
places including python.org, activestate.com and gmane.

> I think we should require 
> subscription before people can post. 

That doesn't achieve much since several lists servers
like gmane are subscribed so anyone on gmane etc can post
(albeit they go into the moderation queue). And the hassle
of subscribing may put some newbies off posting at all,
which we don't want.

> (And I think we should default to individual emails, 
> not daily digest.)

Quite a lot of people use the digest service, especially lurkers.
(A quick scan of the members lists suggests around 35-40%
of all members use digest). I'd be reluctant to remove a
service that is so widely used.

While modern mail tools generally have filters that can do
a similar job I do sympathise with digest users since I used
to be one of them and it was a useful way to keep the mail
count down. But they should take the time to post replies
'nicely'...


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



From alan.gauld at yahoo.co.uk  Sun May  1 05:08:22 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 1 May 2016 10:08:22 +0100
Subject: [Tutor] META: Moderation and subscription to the tutor list
In-Reply-To: <20160501053546.GA3946@cskk.homeip.net>
References: <20160501041826.GB13497@ando.pearwood.info>
 <20160501053546.GA3946@cskk.homeip.net>
Message-ID: <ng4h25$vru$2@ger.gmane.org>

On 01/05/16 06:35, cs at zip.com.au wrote:

> There seems to me a subjectly large number of very short threads with a 
> question from someone, a couple of responses from list members, and no further 
> reply.
> 
> To me this argues that either newcomers are not subscribed and probably do not 
> see any responses, or that sufficient are discourteous enough or naive enough 
> to nothing bother to acknowledge help.

I suspect the latter...

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



From alan.gauld at yahoo.co.uk  Sun May  1 05:25:22 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 1 May 2016 10:25:22 +0100
Subject: [Tutor] META: Moderation and subscription to the tutor list
In-Reply-To: <ng4gv1$vru$1@ger.gmane.org>
References: <20160501041826.GB13497@ando.pearwood.info>
 <ng4gv1$vru$1@ger.gmane.org>
Message-ID: <ng4i22$fko$1@ger.gmane.org>

On 01/05/16 10:06, Alan Gauld via Tutor wrote:

> Quite a lot of people use the digest service, especially lurkers.
> (A quick scan of the members lists suggests around 35-40%
> of all members use digest). I'd be reluctant to remove a
> service that is so widely used.

I've just had a look at the digest options and one possible option
is to send a Mime format digest rather than plain text. I'm not sure
what that would mean in practice but from experience on other
lists it may mean users see individual messages that they can reply to.
This would potentially avoid the long multi-message replies we currently
see. I don't know how it would affect threading.

I therefore propose to switch on MIME digest mode as a trial
at the end of next week if I don't hear a compelling reason
not to...

Hopefully most modern mail tools can handle MIME digests nowadays.

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



From alan.gauld at yahoo.co.uk  Sun May  1 05:36:33 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 1 May 2016 10:36:33 +0100
Subject: [Tutor] META: Moderation and subscription to the tutor list
In-Reply-To: <CANDiX9Kn+NYP2N3S5YszHY87qJM64Y=ENh9ZS=Ah29=ik=2X=w@mail.gmail.com>
References: <20160501041826.GB13497@ando.pearwood.info>
 <20160501053546.GA3946@cskk.homeip.net>
 <CANDiX9Kn+NYP2N3S5YszHY87qJM64Y=ENh9ZS=Ah29=ik=2X=w@mail.gmail.com>
Message-ID: <ng4in1$mhk$1@ger.gmane.org>

On 01/05/16 07:23, boB Stepp wrote:

> I am in agreement with this as well.  I have often wondered if
> newcomers are subscribed or not

Most are. Several who are not, subscribe very soon
after - presumably in response to the intro message.

>  as after subscription one receives a
> very helpful email which addresses most of the common post formatting
> issues that we seem to endlessly rehash.  Or perhaps I am one of the
> few who actually read it upon subscribing?

Probably most don't read it (all). But many simply are not
technically savvy enough to know how to post in plain text,
or avoid top posting etc. There are foreign concepts to many
of the modern generation of internet users.

> I wonder no matter which way the current matter gets decided, if it
> might be time to rewrite the automated response email.  

I'm open to suggestions on this. It has gradually grown over
the years as new caveats get added. A rewrite is something
that is within our remit and abilities without involving
the list admins.

> mentioned.  It probably should be added.  I feel that the interleaved
> writing style employed by many lists is completely foreign to
> newcomers to programming.

Absolutely. In fact even some programmers have never come
across it because it's not how most web forums (fora?) work.
And business email is now almost universally on Outlook/Exchange
and top posting is the norm.

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



From steve at pearwood.info  Sun May  1 06:43:38 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 1 May 2016 20:43:38 +1000
Subject: [Tutor] int(1.99...99) = 1 and can = 2
In-Reply-To: <CANDiX9KD3Jz+3FKFYDrSepXgo11FVM6ZAZrJAzc_QZ1ceRMOoA@mail.gmail.com>
References: <CANDiX9KD3Jz+3FKFYDrSepXgo11FVM6ZAZrJAzc_QZ1ceRMOoA@mail.gmail.com>
Message-ID: <20160501104338.GC13497@ando.pearwood.info>

On Sun, May 01, 2016 at 01:02:50AM -0500, boB Stepp wrote:
> Life has kept me from Python studies since March, but now I resume.
> Playing around in the interpreter I tried:
> 
> py3: 1.9999999999999999
> 2.0
> py3: 1.999999999999999
> 1.999999999999999

Correct. Python floats carry 64 bits of value, which means in 
practice that they can carry about 16-17 significant figures in 
decimal. 

Starting with Python 2.6, floats have "hex" and "fromhex" methods which 
allow you to convert them to and from base 16, which is more compact 
than the base 2 used internally but otherwise equivalent.

https://docs.python.org/2/library/stdtypes.html#float.hex

So here is your second example, shown in hex so we can get a better 
idea of the internal details:

py> (1.999999999999999).hex()
'0x1.ffffffffffffbp+0'

The "p+0" at the end shows the exponent, as a power of 2. (It can't use 
"e" or "E" like decimal, because that would be confused with the hex 
digit "e".)

You can see that the last hex digit is "b". If we add an extra digit to 
the end of the decimal 1.999999999999999, that final digit increases 
until we reach:

py> (1.9999999999999997).hex()
'0x1.fffffffffffffp+0'

1.9999999999999998 also gives us the same result. More on this later.

If we increase the final decimal digit one more, we get:

py> (1.9999999999999999).hex()
'0x1.0000000000000p+1'

which is equal to decimal 2: a mantissa of 1 in hex, an exponent of 1 
in decimal, which gives 1*2**1 = 2.


Given that we only have 64 bits for a float, and some of them are used 
for the exponent and the sign, it is invariable that conversions to and 
from decimal must be inexact. Remember that I mentioned that both 
1.9999999999999997 and 1.9999999999999998 are treated as the same float? 
That is because a 64-bit binary float does not have enough binary 
decimal places to distinguish them. You would need more than 64 bits to 
tell them apart. And so, following the IEEE-754 standard (the best 
practice for floating point arithmetic), both numbers are rounded to the 
nearest possible float.

Why the nearest possible float? Because any other choice, such as 
"always round down", or "always round up", or "round up on Tuesdays", 
will have *larger* rounding errors. Rounding errors are inescapable, but 
we can do what we can to keep them as small as possible. So, decimal 
strings like 1.999...97 generate the binary float with the smallest 
possible error.

(In fact, the IEEE-754 standard requires that the rounding mode be 
user-configurable. Unfortunately, most C maths library do not provide 
that functionality, or if they do, it is not reliable.)

A diagram might help make this more clear. This ASCII art is best viewed 
using a fixed-width font like Courier.

Suppose we look at every single float between 1 and 2. Since they use
a finite number of bits, there are a finite number of equally spaced 
floats between any two consecutive whole numbers. But because they are 
in binary, not decimal, they won't match up with decimal floats except 
for numbers like 0.5, 0.25 etc. So:


1 _____ | _____ | _____ | _____ | ... | _____ | _____ | _____ 2
---------------------------------------------------^----^---^
                                                   a    b   c


The first arrow ^ marked as "a" represents the true position of 
1.999...97 and the second, "b", represents the true position of 
1.999...98. Since they don't line up exactly with the binary float 
0x1.ffff....ff, there is some rounding error, but it is the smallest 
error possible.

The third arrow, marked as "c", represents 1.999...99.



> py3: int(1.9999999999999999)
> 2
> py3: int(1.999999999999999)
> 1

The int() function always truncates. So in the first place, your float 
starts off as 2.0 (as seen above), and then int() truncates it to 2.0. 
The second case starts off as with a float 1.9999... which is

'0x1.ffffffffffffbp+0'

which int() then truncates to 1.


> It has been many years since I did problems in converting decimal to
> binary representation (Shades of two's-complement!), but I am under
> the (apparently mistaken!) impression that in these 0.999...999
> situations that the floating point representation should not go "up"
> in value to the next integer representation.

In ancient days, by which I mean the earlier than the 1980s, there was 
no agreement on how floats should be rounded by computer manufacturers. 
Consequently they all used their own rules, which contradicted the rules 
used by other manufacturers, and sometimes even their own. But in the 
early 80s, a consortium of companies including Apple, Intel and others 
got together and agreed on best practices (give or take a few 
compromises) for computer floating point maths. One of those is that the 
default rounding mode should be round to nearest, so as to minimize the 
errors. Otherwise, if you always round down, then errors accumulate 
faster.

We can test this with the fractions and decimal modules:

py> from fractions import Fraction
py> f = Fraction(0)
py> for i in range(1, 100):
...     f += Fraction(1)/i
...
py> f
Fraction(360968703235711654233892612988250163157207, 
69720375229712477164533808935312303556800)
py> float(f)
5.17737751763962

So that tells us the exact result of adding the recipricals of 1 through 
99, and the nearest binary float. Now let's do it again, only this time 
with only limited precision:

py> from decimal import *
py> d = Decimal(0)
py> with localcontext() as ctx:
...     ctx.prec = 5
...     for i in range(1, 100):
...             d += Decimal(1)/i
...
py> d
Decimal('5.1773')

That's not too bad: four out of the five significant figures are 
correct, the the fifth is only off by one. (It should be 5.1774 if we 
added exactly, and rounded only at the end.) But if we change to always 
round down:

py> d = Decimal(0)
py> with localcontext() as ctx:
...     ctx.prec = 5
...     ctx.rounding = ROUND_DOWN
...     for i in range(1, 100):
...             d += Decimal(1)/i
...
py> d
Decimal('5.1734')


we're now way off: only three significant figures are correct, and the 
fourth is off by 4.

Obviously this is an extreme case, for demonstration purposes only. But 
the principle is the same for floats: the IEEE 754 promise to keep 
simple arithmetic is correctly rounded ensures that errors are as small 
as possible.


-- 
Steve

From thomasolaoluwa at gmail.com  Sun May  1 07:55:27 2016
From: thomasolaoluwa at gmail.com (Olaoluwa Thomas)
Date: Sun, 1 May 2016 12:55:27 +0100
Subject: [Tutor] Issues converting a script to a functioin (or something)
Message-ID: <CABq_6ePiezPizOi6prUNf_YxiB_5aNcn2yjLy84U0pNzmTZ_eA@mail.gmail.com>

The novice Python programmer is back.

I'm trying to incorporate a function and its call in the GrossPay.py script
that Alan solved for me.
It computes total pay based on two inputs, no. of hours and hourly rate.

There's a computation for overtime payments in the if statement.

Something seems to be broken.

Here's the code:
def computepay(hours, rate):
    hours = float(raw_input ('How many hours do you work?\n'))
    rate = float(raw_input ('What is your hourly rate?\n'))
    if hours > 40:
        gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
    elif hours >= 0 and hours <= 40:
        gross = hours * rate
    print "Your Gross pay is "+str(round(gross, 4))

computepay()

What am I doing wrong?

*Warm regards,*

*Olaoluwa O. Thomas,*
*+2347068392705*

From bgailer at gmail.com  Sun May  1 09:13:44 2016
From: bgailer at gmail.com (Bob Gailer)
Date: Sun, 1 May 2016 09:13:44 -0400
Subject: [Tutor] Issues converting a script to a functioin (or something)
In-Reply-To: <CABq_6ePiezPizOi6prUNf_YxiB_5aNcn2yjLy84U0pNzmTZ_eA@mail.gmail.com>
References: <CABq_6ePiezPizOi6prUNf_YxiB_5aNcn2yjLy84U0pNzmTZ_eA@mail.gmail.com>
Message-ID: <CAP1rxO7AGVKmMXZrXMhd+7eGcJ8sGFwU9r6Ho5FBmL95T7qD_Q@mail.gmail.com>

On May 1, 2016 8:04 AM, "Olaoluwa Thomas" <thomasolaoluwa at gmail.com> wrote:
>
> The novice Python programmer is back.
Welcome back. We are here to help you when you are stuck. Telling us
something is broken is not adequate. Tell us-what you are expecting the
program to do and what results you're getting.
>
> I'm trying to incorporate a function and its call in the GrossPay.py
script
> that Alan solved for me.
> It computes total pay based on two inputs, no. of hours and hourly rate.
>
> There's a computation for overtime payments in the if statement.
>
> Something seems to be broken.
>
> Here's the code:
> def computepay(hours, rate):
>     hours = float(raw_input ('How many hours do you work?\n'))
>     rate = float(raw_input ('What is your hourly rate?\n'))
>     if hours > 40:
>         gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
>     elif hours >= 0 and hours <= 40:
>         gross = hours * rate
>     print "Your Gross pay is "+str(round(gross, 4))
>
> computepay()
>
> What am I doing wrong?
>
> *Warm regards,*
>
> *Olaoluwa O. Thomas,*
> *+2347068392705*
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From bgailer at gmail.com  Sun May  1 09:21:17 2016
From: bgailer at gmail.com (Bob Gailer)
Date: Sun, 1 May 2016 09:21:17 -0400
Subject: [Tutor] Python Homework
In-Reply-To: <CA+KwKjp6XH1Ue4y9WVb0a7GqXJURgzD+haJZckF8WLFYBH4+hA@mail.gmail.com>
References: <CA+KwKjp6XH1Ue4y9WVb0a7GqXJURgzD+haJZckF8WLFYBH4+hA@mail.gmail.com>
Message-ID: <CAP1rxO4zawsiiAa8ZgLfm8hBS=RdN9jM-b+ApaeoK5yvq8bBgg@mail.gmail.com>

On May 1, 2016 4:33 AM, "Katie Tuite" <katuite13 at gmail.com> wrote:
>
> I'm trying to do a python homework question and cannot figure out how to
> start at all.
>
> This is the question
>
> [image: pasted1]
As you can see attachments don't work. Include the code in your post.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From thomasolaoluwa at gmail.com  Sun May  1 09:38:23 2016
From: thomasolaoluwa at gmail.com (Olaoluwa Thomas)
Date: Sun, 1 May 2016 14:38:23 +0100
Subject: [Tutor] Issues converting a script to a functioin (or
 something) [SOLVED]
Message-ID: <CABq_6eOSBtMuOmpmCZgAjzg5ApfnjE3qYc6rF8Rs9axS1zu2OQ@mail.gmail.com>

Hi Bob,

Thanks for your feedback. Please do not hesitate to provide more as I shall
email you personally in the future.

The script is made up of a function definition and its call prompting the
user for input.

The script itself takes "number of hours worked" and "hourly rate" as
inputs and gives gross pay as a product of the two.
As I stated in my earlier email, there is also a portion for calculating
gross pay with considerations for overtime (> 40 hours worked).

The problem was that running the code gave an error which I now do not
remember in detail as I have moved on after having fixed it.

Here's the initial email below with Sreenathan's helpful input followed by
my amendments to the code:
(I thought my initial email was quite self-explanatory but what do I
know... Please read through to the end)

On Sun, May 1, 2016 at 1:09 PM, Sreenathan Nair <sreenath.cg at gmail.com>
 wrote:

> On Sun, May 01, 2016 at 5:34 PM, Olaoluwa Thomas <thomasolaoluwa at gmail.com>
> wrote:
>
> The novice Python programmer is back.
>
> I'm trying to incorporate a function and its call in the GrossPay.py
> script
> that Alan solved for me.
> It computes total pay based on two inputs, no. of hours and hourly rate.
>
> There's a computation for overtime payments in the if statement.
>
> Something seems to be broken.
>
> Here's the code:
> def computepay(hours, rate):
>     hours = float(raw_input ('How many hours do you work?\n'))
>     rate = float(raw_input ('What is your hourly rate?\n'))
>     if hours > 40:
>         gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
>     elif hours >= 0 and hours <= 40:
>         gross = hours * rate
>     print "Your Gross pay is "+str(round(gross, 4))
>
> computepay()
>
> What am I doing wrong?
>
> *Warm regards,*
>
> *Olaoluwa O. Thomas,*
> *+2347068392705*
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
>  Hi,
> The parameters hours and rate are required when calling the method
> computepay ex: computepay(8, 200), so basically computepay() by itself will
> throw an error .... Also, as a suggestion if you're gonna get hours and
> rate via user input perhaps they can be removed from the method definition?
>
> ?Thanks, Sreenathan. These alterations solved it.

def computepay(hours, rate):
    if hours > 40:
        gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
    elif hours >= 0 and hours <= 40:
        gross = hours * rate
    print "Your Gross pay is "+str(round(gross, 4))
computepay(hours = float(raw_input ('How many hours do you work?\n')), rate
= float(raw_input ('What is your hourly rate?\n')))

*Warm regards,*

*Olaoluwa O. Thomas,*
*+2347068392705*

On Sun, May 1, 2016 at 2:13 PM, Bob Gailer <bgailer at gmail.com> wrote:

>
> On May 1, 2016 8:04 AM, "Olaoluwa Thomas" <thomasolaoluwa at gmail.com>
> wrote:
> >
> > The novice Python programmer is back.
> Welcome back. We are here to help you when you are stuck. Telling us
> something is broken is not adequate. Tell us-what you are expecting the
> program to do and what results you're getting.
> >
> > I'm trying to incorporate a function and its call in the GrossPay.py
> script
> > that Alan solved for me.
> > It computes total pay based on two inputs, no. of hours and hourly rate.
> >
> > There's a computation for overtime payments in the if statement.
> >
> > Something seems to be broken.
> >
> > Here's the code:
> > def computepay(hours, rate):
> >     hours = float(raw_input ('How many hours do you work?\n'))
> >     rate = float(raw_input ('What is your hourly rate?\n'))
> >     if hours > 40:
> >         gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
> >     elif hours >= 0 and hours <= 40:
> >         gross = hours * rate
> >     print "Your Gross pay is "+str(round(gross, 4))
> >
> > computepay()
> >
> > What am I doing wrong?
> >
> > *Warm regards,*
> >
> > *Olaoluwa O. Thomas,*
> > *+2347068392705*
> > _______________________________________________
> > Tutor maillist  -  Tutor at python.org
> > To unsubscribe or change subscription options:
> > https://mail.python.org/mailman/listinfo/tutor
>

From badouglas at gmail.com  Sun May  1 12:49:27 2016
From: badouglas at gmail.com (bruce)
Date: Sun, 1 May 2016 12:49:27 -0400
Subject: [Tutor] simple regex question
Message-ID: <CAP16ngpnMJdfGdm9UObiDyaAEEN1CQcFZRmDugDQVTQi522D9Q@mail.gmail.com>

Hi. I have a chunk of text code, which has multiple lines.

I'd like to do a regex, find a pattern, and in the line that matches the
pattern, mod the line. Sounds simple.

I've created a test regex. However, after spending time/google.. can't
quite figure out how to then get the "complete" line containing the
returned regex/pattern.

Pretty sure this is simple, and i'm just missing something.

my test "text" and regex are:


  s='''
<td valign="top" colspan="1"><b><a href="#"
id='CourseId10795788|ACCT2081|002_005_006' style="font-weight:bold;"
onclick='ShowSeats(this);return false;' alt="Click for Class Availability"
title="Click for Class Availability">ACCT2081</a></b></td>'''


  pattern = re.compile(r'Course\S+|\S+\|')
  aa= pattern.search(s).group()
  print "sss"
  print aa

so, once I get the group, I'd like to use the returned match to then get
the complete line..

pointers/thoughts!! (no laughing!!)

thanks guys..

From __peter__ at web.de  Sun May  1 13:46:46 2016
From: __peter__ at web.de (Peter Otten)
Date: Sun, 01 May 2016 19:46:46 +0200
Subject: [Tutor] simple regex question
References: <CAP16ngpnMJdfGdm9UObiDyaAEEN1CQcFZRmDugDQVTQi522D9Q@mail.gmail.com>
Message-ID: <ng5fe7$n4b$1@ger.gmane.org>

bruce wrote:

> Hi. I have a chunk of text code, which has multiple lines.
> 
> I'd like to do a regex, find a pattern, and in the line that matches the
> pattern, mod the line. Sounds simple.
> 
> I've created a test regex. However, after spending time/google.. can't
> quite figure out how to then get the "complete" line containing the
> returned regex/pattern.
> 
> Pretty sure this is simple, and i'm just missing something.
> 
> my test "text" and regex are:
> 
> 
>   s='''
> <td valign="top" colspan="1"><b><a href="#"
> id='CourseId10795788|ACCT2081|002_005_006' style="font-weight:bold;"
> onclick='ShowSeats(this);return false;' alt="Click for Class Availability"
> title="Click for Class Availability">ACCT2081</a></b></td>'''
> 
> 
>   pattern = re.compile(r'Course\S+|\S+\|')
>   aa= pattern.search(s).group()
>   print "sss"
>   print aa
> 
> so, once I get the group, I'd like to use the returned match to then get
> the complete line..
> 
> pointers/thoughts!! (no laughing!!)

Are you sure you are processing text rather than structured data? HTML 
doesn't have the notion of a "line". To extract information from HTML tools 
like Beautiful Soup are better suited than regular expressions:

import bs4
import re
s = ...
soup = bs4.BeautifulSoup(s)
for a in soup.find_all("a", id=re.compile(r"Course\S+\|\S+\|")):
    print a["id"]
    print a.text
    print a.parent.parent["colspan"]



From itetteh34 at hotmail.com  Sun May  1 10:19:27 2016
From: itetteh34 at hotmail.com (isaac tetteh)
Date: Sun, 1 May 2016 09:19:27 -0500
Subject: [Tutor] Issues converting a script to a functioin (or
 something) [SOLVED]
In-Reply-To: <CABq_6eOSBtMuOmpmCZgAjzg5ApfnjE3qYc6rF8Rs9axS1zu2OQ@mail.gmail.com>
References: <CABq_6eOSBtMuOmpmCZgAjzg5ApfnjE3qYc6rF8Rs9axS1zu2OQ@mail.gmail.com>
Message-ID: <DUB407-EAS332B278AF4F769E5DD4D791BD780@phx.gbl>

You have two arguments in you function but when you call the function no argument is set in. Take the arguments out from the function if you want to use the the values from the user. 

Sent from my iPhone

> On May 1, 2016, at 8:41 AM, Olaoluwa Thomas <thomasolaoluwa at gmail.com> wrote:
> 
> Hi Bob,
> 
> Thanks for your feedback. Please do not hesitate to provide more as I shall
> email you personally in the future.
> 
> The script is made up of a function definition and its call prompting the
> user for input.
> 
> The script itself takes "number of hours worked" and "hourly rate" as
> inputs and gives gross pay as a product of the two.
> As I stated in my earlier email, there is also a portion for calculating
> gross pay with considerations for overtime (> 40 hours worked).
> 
> The problem was that running the code gave an error which I now do not
> remember in detail as I have moved on after having fixed it.
> 
> Here's the initial email below with Sreenathan's helpful input followed by
> my amendments to the code:
> (I thought my initial email was quite self-explanatory but what do I
> know... Please read through to the end)
> 
> On Sun, May 1, 2016 at 1:09 PM, Sreenathan Nair <sreenath.cg at gmail.com>
> wrote:
> 
>> On Sun, May 01, 2016 at 5:34 PM, Olaoluwa Thomas <thomasolaoluwa at gmail.com>
>> wrote:
>> 
>> The novice Python programmer is back.
>> 
>> I'm trying to incorporate a function and its call in the GrossPay.py
>> script
>> that Alan solved for me.
>> It computes total pay based on two inputs, no. of hours and hourly rate.
>> 
>> There's a computation for overtime payments in the if statement.
>> 
>> Something seems to be broken.
>> 
>> Here's the code:
>> def computepay(hours, rate):
>>    hours = float(raw_input ('How many hours do you work?\n'))
>>    rate = float(raw_input ('What is your hourly rate?\n'))
>>    if hours > 40:
>>        gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
>>    elif hours >= 0 and hours <= 40:
>>        gross = hours * rate
>>    print "Your Gross pay is "+str(round(gross, 4))
>> 
>> computepay()
>> 
>> What am I doing wrong?
>> 
>> *Warm regards,*
>> 
>> *Olaoluwa O. Thomas,*
>> *+2347068392705*
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> https://mail.python.org/mailman/listinfo/tutor
>> 
>> Hi,
>> The parameters hours and rate are required when calling the method
>> computepay ex: computepay(8, 200), so basically computepay() by itself will
>> throw an error .... Also, as a suggestion if you're gonna get hours and
>> rate via user input perhaps they can be removed from the method definition?
>> 
>> ?Thanks, Sreenathan. These alterations solved it.
> 
> def computepay(hours, rate):
>    if hours > 40:
>        gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
>    elif hours >= 0 and hours <= 40:
>        gross = hours * rate
>    print "Your Gross pay is "+str(round(gross, 4))
> computepay(hours = float(raw_input ('How many hours do you work?\n')), rate
> = float(raw_input ('What is your hourly rate?\n')))
> 
> *Warm regards,*
> 
> *Olaoluwa O. Thomas,*
> *+2347068392705*
> 
>> On Sun, May 1, 2016 at 2:13 PM, Bob Gailer <bgailer at gmail.com> wrote:
>> 
>> 
>> On May 1, 2016 8:04 AM, "Olaoluwa Thomas" <thomasolaoluwa at gmail.com>
>> wrote:
>>> 
>>> The novice Python programmer is back.
>> Welcome back. We are here to help you when you are stuck. Telling us
>> something is broken is not adequate. Tell us-what you are expecting the
>> program to do and what results you're getting.
>>> 
>>> I'm trying to incorporate a function and its call in the GrossPay.py
>> script
>>> that Alan solved for me.
>>> It computes total pay based on two inputs, no. of hours and hourly rate.
>>> 
>>> There's a computation for overtime payments in the if statement.
>>> 
>>> Something seems to be broken.
>>> 
>>> Here's the code:
>>> def computepay(hours, rate):
>>>    hours = float(raw_input ('How many hours do you work?\n'))
>>>    rate = float(raw_input ('What is your hourly rate?\n'))
>>>    if hours > 40:
>>>        gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
>>>    elif hours >= 0 and hours <= 40:
>>>        gross = hours * rate
>>>    print "Your Gross pay is "+str(round(gross, 4))
>>> 
>>> computepay()
>>> 
>>> What am I doing wrong?
>>> 
>>> *Warm regards,*
>>> 
>>> *Olaoluwa O. Thomas,*
>>> *+2347068392705*
>>> _______________________________________________
>>> 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 sreenath.cg at gmail.com  Sun May  1 08:09:57 2016
From: sreenath.cg at gmail.com (Sreenathan Nair)
Date: Sun, 01 May 2016 17:39:57 +0530
Subject: [Tutor] Issues converting a script to a functioin (or something)
In-Reply-To: <CABq_6ePiezPizOi6prUNf_YxiB_5aNcn2yjLy84U0pNzmTZ_eA@mail.gmail.com>
References: <CABq_6ePiezPizOi6prUNf_YxiB_5aNcn2yjLy84U0pNzmTZ_eA@mail.gmail.com>
Message-ID: <1462104600630-b5f5e23a-749f107e-ad3b634b@gmail.com>

On Sun, May 01, 2016 at 5:34 PM, Olaoluwa Thomas < thomasolaoluwa at gmail.com 
[thomasolaoluwa at gmail.com] > wrote:
The novice Python programmer is back.

I'm trying to incorporate a function and its call in the GrossPay.py script
that Alan solved for me.
It computes total pay based on two inputs, no. of hours and hourly rate.

There's a computation for overtime payments in the if statement.

Something seems to be broken.

Here's the code:
def computepay(hours, rate):
hours = float(raw_input ('How many hours do you work?\n'))
rate = float(raw_input ('What is your hourly rate?\n'))
if hours > 40:
gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
elif hours >= 0 and hours <= 40:
gross = hours * rate
print "Your Gross pay is "+str(round(gross, 4))

computepay()

What am I doing wrong?

*Warm regards,*

*Olaoluwa O. Thomas,*
*+2347068392705*
_______________________________________________
Tutor maillist - Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor




Hi, The parameters hours and rate are required when calling the method 
computepay ex: computepay(8, 200), so basically computepay() by itself will 
throw an error .... Also, as a suggestion if you're gonna get hours and 
rate via user input perhaps they can be removed from the method definition?

From alan.gauld at yahoo.co.uk  Sun May  1 14:09:46 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 1 May 2016 19:09:46 +0100
Subject: [Tutor] Issues converting a script to a functioin (or something)
In-Reply-To: <CABq_6ePiezPizOi6prUNf_YxiB_5aNcn2yjLy84U0pNzmTZ_eA@mail.gmail.com>
References: <CABq_6ePiezPizOi6prUNf_YxiB_5aNcn2yjLy84U0pNzmTZ_eA@mail.gmail.com>
Message-ID: <ng5gp9$al7$1@ger.gmane.org>

On 01/05/16 12:55, Olaoluwa Thomas wrote:

> It computes total pay based on two inputs, no. of hours and hourly rate.

While you do specify two inputs you immediately throw them away
and ask the user to provide the information. In general it is good
practice to separate calculation from input/output operations.
So in your case write the function to take the values provided by the
user and return(not print) the result.

Then when you call the function you pass in the values from the
user and print the function output. This makes the function more
likely to be reusable in other scenarios and easier to debug/test.

def computePay(hours, rate):
   # an exercise for the reader...

hours = float(raw_input ('How many hours do you work?\n'))
rate = float(raw_input ('What is your hourly rate?\n'))
print computPay(hours, rate)

> Something seems to be broken.

You must learn to provide more specific comments.
Define what is broken. Do you get an error message?
If so send it (all of it, not just a summary)
If no error message what output did you get?
What did you expect?

Otherwise we wind up just guessing at what is going on.
(And only a fool would run allegedly faulty code from
  an unknown source! :-)

> Here's the code:
> def computepay(hours, rate):
>     hours = float(raw_input ('How many hours do you work?\n'))
>     rate = float(raw_input ('What is your hourly rate?\n'))
>     if hours > 40:
>         gross = ((hours - 40) * (rate * 1.5)) + (40 * rate)
>     elif hours >= 0 and hours <= 40:
>         gross = hours * rate
>     print "Your Gross pay is "+str(round(gross, 4))
> 
> computepay()

In this cae I'll guess it's the fact that you tell Python that
computePay is a function that takes two arguments (hours, rate)
but then call it with no arguments. But you should have got
an error message saying something very like that?
Here is what I get:

>>> def f(x,y): pass
...
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() missing 2 required positional arguments: 'x' and 'y'
>>>

That's why including the error message helps  so much...

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



From alan.gauld at yahoo.co.uk  Sun May  1 14:14:14 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 1 May 2016 19:14:14 +0100
Subject: [Tutor] Issues converting a script to a functioin (or
 something) [SOLVED]
In-Reply-To: <CABq_6eOSBtMuOmpmCZgAjzg5ApfnjE3qYc6rF8Rs9axS1zu2OQ@mail.gmail.com>
References: <CABq_6eOSBtMuOmpmCZgAjzg5ApfnjE3qYc6rF8Rs9axS1zu2OQ@mail.gmail.com>
Message-ID: <ng5h1l$el4$1@ger.gmane.org>

On 01/05/16 14:38, Olaoluwa Thomas wrote:

> Thanks for your feedback. Please do not hesitate to provide more as I shall
> email you personally in the future.

Please don't do that.
a) Bob is a busy man who volunteers his time here, but may
   have other things to do too.
b) The list is here so that everyone can benefit from the
   discussions not only the people actively involved.


> The problem was that running the code gave an error which I now do not
> remember in detail as I have moved on after having fixed it.

But the answer is nearly always in the detail. And as you get
more advanced in coding the errors get harder to spot. That's
why it is important to supply us (or any other forum) with
as much detail as you can.


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



From alan.gauld at yahoo.co.uk  Sun May  1 14:24:09 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 1 May 2016 19:24:09 +0100
Subject: [Tutor] simple regex question
In-Reply-To: <CAP16ngpnMJdfGdm9UObiDyaAEEN1CQcFZRmDugDQVTQi522D9Q@mail.gmail.com>
References: <CAP16ngpnMJdfGdm9UObiDyaAEEN1CQcFZRmDugDQVTQi522D9Q@mail.gmail.com>
Message-ID: <ng5hk8$n3k$1@ger.gmane.org>

On 01/05/16 17:49, bruce wrote:
> Hi. I have a chunk of text code, which has multiple lines.

>   s='''
> <td valign="top" colspan="1"><b><a href="#"
> id='CourseId10795788|ACCT2081|002_005_006' style="font-weight:bold;"
> onclick='ShowSeats(this);return false;' alt="Click for Class Availability"
> title="Click for Class Availability">ACCT2081</a></b></td>'''

That looks like HTML. regex won't work reliably on HTML.
You would be better using an HTML parser like BeautifulSoup
or even the standard library's html.parser(Python v3).
That will give more precise and reliable results for only
a little more effort.

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



From thomasolaoluwa at gmail.com  Sun May  1 16:08:42 2016
From: thomasolaoluwa at gmail.com (Olaoluwa Thomas)
Date: Sun, 1 May 2016 21:08:42 +0100
Subject: [Tutor] Issues converting a script to a functioin (or
 something) [SOLVED]
In-Reply-To: <ng5h1l$el4$1@ger.gmane.org>
References: <CABq_6eOSBtMuOmpmCZgAjzg5ApfnjE3qYc6rF8Rs9axS1zu2OQ@mail.gmail.com>
 <ng5h1l$el4$1@ger.gmane.org>
Message-ID: <CABq_6ePpMaPmzycPvvEW5eBP+Rf_gu=7Asv7yRYZOxouAhLwmA@mail.gmail.com>

Gotcha.

*Warm regards,*

*Olaoluwa O. Thomas,*
*+2347068392705*

On Sun, May 1, 2016 at 7:14 PM, Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 01/05/16 14:38, Olaoluwa Thomas wrote:
>
> > Thanks for your feedback. Please do not hesitate to provide more as I
> shall
> > email you personally in the future.
>
> Please don't do that.
> a) Bob is a busy man who volunteers his time here, but may
>    have other things to do too.
> b) The list is here so that everyone can benefit from the
>    discussions not only the people actively involved.
>
>
> > The problem was that running the code gave an error which I now do not
> > remember in detail as I have moved on after having fixed it.
>
> But the answer is nearly always in the detail. And as you get
> more advanced in coding the errors get harder to spot. That's
> why it is important to supply us (or any other forum) with
> as much detail as you can.
>
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From nymcity at yahoo.com  Sun May  1 16:15:35 2016
From: nymcity at yahoo.com (Jason N.)
Date: Sun, 1 May 2016 20:15:35 +0000 (UTC)
Subject: [Tutor] "List" object is not callable
In-Reply-To: <20160501031145.GY13497@ando.pearwood.info>
References: <1105117411.4367773.1462042277993.JavaMail.yahoo.ref@mail.yahoo.com>
 <1105117411.4367773.1462042277993.JavaMail.yahoo@mail.yahoo.com>
 <20160501031145.GY13497@ando.pearwood.info>
Message-ID: <43738529.4474383.1462133735123.JavaMail.yahoo@mail.yahoo.com>

Thank you all for your responses.?
I am using Py 2.7 and this time I copied and pasted the code from here: http://www.opentechguides.com/how-to/article/python/57/python-ping-subnet.html?to my system but received the same error when I ran it.?
You can see the error screenshot here:?https://unsee.cc/sonezima/?Thank you. 

    On Saturday, April 30, 2016 11:12 PM, Steven D'Aprano <steve at pearwood.info> wrote:
 
 

 On Sat, Apr 30, 2016 at 06:51:17PM +0000, Jason N. via Tutor wrote:
> Hello,
> I found this simple script online but when I execute it I get the 
> following error: "TypeError: 'list' object is not callable" Here is 
> the code sample:
>
> import subprocess
> ls_output= subprocess.check_output(['dir'])

The code snippet works fine.

Please check that the code you send is exactly the same as the code you 
are actually trying to run. Do not just retype the code from memory, 
copy and paste it.

Also, please copy and paste the full traceback that you get, not just 
the final error message. Everything from the first "Traceback" line to 
the end.

Finally, you should tell us what version of Python you are running, on 
what operating system (Linux, Mac OS, Windows XP, Windows 10, Android, 
something else), and whether you are using the standard Python 
interactive interpreter or something else (IDLE, iPython, Anaconda, 
PyCharm, etc.).


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


 
  

From robertvstepp at gmail.com  Sun May  1 16:38:32 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 1 May 2016 15:38:32 -0500
Subject: [Tutor] int(1.99...99) = 1 and can = 2
In-Reply-To: <20160501104338.GC13497@ando.pearwood.info>
References: <CANDiX9KD3Jz+3FKFYDrSepXgo11FVM6ZAZrJAzc_QZ1ceRMOoA@mail.gmail.com>
 <20160501104338.GC13497@ando.pearwood.info>
Message-ID: <CANDiX9LDWfaeAwLQWU4Ao+-5Fz9HE1uaxZg343JWiD+-GqJPkw@mail.gmail.com>

On Sun, May 1, 2016 at 5:43 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Sun, May 01, 2016 at 01:02:50AM -0500, boB Stepp wrote:
>> Life has kept me from Python studies since March, but now I resume.
>> Playing around in the interpreter I tried:
>>
>> py3: 1.9999999999999999
>> 2.0
>> py3: 1.999999999999999
>> 1.999999999999999

[...]

> Starting with Python 2.6, floats have "hex" and "fromhex" methods which
> allow you to convert them to and from base 16, which is more compact
> than the base 2 used internally but otherwise equivalent.
>
> https://docs.python.org/2/library/stdtypes.html#float.hex

I had not read of these methods yet.  Thanks!

[...]


> Given that we only have 64 bits for a float, and some of them are used
> for the exponent and the sign, it is invariable that conversions to and
> from decimal must be inexact. Remember that I mentioned that both
> 1.9999999999999997 and 1.9999999999999998 are treated as the same float?
> That is because a 64-bit binary float does not have enough binary
> decimal places to distinguish them. You would need more than 64 bits to
> tell them apart. And so, following the IEEE-754 standard (the best
> practice for floating point arithmetic), both numbers are rounded to the
> nearest possible float.

Just before bed, I was looking at the Wikipedia article on IEEE-754.
But it was not clear from it which of the "optional" rounding methods
were being used by Python, though the behavior I was observing
suggested rounding to nearest.

[...]

>> It has been many years since I did problems in converting decimal to
>> binary representation (Shades of two's-complement!), but I am under
>> the (apparently mistaken!) impression that in these 0.999...999
>> situations that the floating point representation should not go "up"
>> in value to the next integer representation.
>
> In ancient days, by which I mean the earlier than the 1980s, ...

Heavy sigh!  I last explicitly did binary arithmetic in an Intro to C.
Sc. class in 1975.  So perhaps my incorrect expectation of *not*
rounding up is an artifact of that long ago era.

Thank you Steve, and Eryk, for your excellent explanations!  I really
appreciate the time and depth both of you put into your answers to my
questions.

boB

From alan.gauld at yahoo.co.uk  Sun May  1 19:08:14 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 2 May 2016 00:08:14 +0100
Subject: [Tutor] simple regex question
In-Reply-To: <CAP16ngrqa2bWNj1VxC8vmr6Mi0ANKPWmRFzBUTtkFZKV1tA9gg@mail.gmail.com>
References: <CAP16ngpnMJdfGdm9UObiDyaAEEN1CQcFZRmDugDQVTQi522D9Q@mail.gmail.com>
 <ng5hk8$n3k$1@ger.gmane.org>
 <CAP16ngrqa2bWNj1VxC8vmr6Mi0ANKPWmRFzBUTtkFZKV1tA9gg@mail.gmail.com>
Message-ID: <57268C5E.6030703@yahoo.co.uk>

On 01/05/16 20:04, bruce wrote:
> Hey all..
>
> Yeah, the sample I'm dealing with is html.. I'm doing some "complex"
> extraction, and i'm modifying the text to make it easier/more robust..
>
> So, in this case, the ability to generate the line is what's needed
> for the test..
>

But as Peter explained HTML has no concept of a "line". Trying to extract a
line from HTML depends totally on how the HTML is formatted by the author
in the original file, but if you read it from a web server it may totally
rearrange the content(while maintaining the HTML), thus breaking your code.
Similarly if it gets sent via an email or some other mechanism.

What you really want will be defined by the tags within which it lives.
And that's what a parser does - finds tags and extracts the content.
A regex can only do that for a very limited set of inputs. and it certainly
can't guarantee a "line" of output. Even if it seems to work today it
could fail completely next week even if the original HTML doesn't change.

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


From nymcity at yahoo.com  Sun May  1 21:27:42 2016
From: nymcity at yahoo.com (Jason N.)
Date: Mon, 2 May 2016 01:27:42 +0000 (UTC)
Subject: [Tutor] "List" object is not callable
In-Reply-To: <43738529.4474383.1462133735123.JavaMail.yahoo@mail.yahoo.com>
References: <1105117411.4367773.1462042277993.JavaMail.yahoo.ref@mail.yahoo.com>
 <1105117411.4367773.1462042277993.JavaMail.yahoo@mail.yahoo.com>
 <20160501031145.GY13497@ando.pearwood.info>
 <43738529.4474383.1462133735123.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <1321628508.4510467.1462152462673.JavaMail.yahoo@mail.yahoo.com>

Hello,
I figured out the issue. It was a silly mistake - i was not running the correct code; instead was running code from another program which was active on a second tab.?Thank you. 

    On Sunday, May 1, 2016 4:15 PM, Jason N. via Tutor <tutor at python.org> wrote:
 
 

 Thank you all for your responses.?
I am using Py 2.7 and this time I copied and pasted the code from here: http://www.opentechguides.com/how-to/article/python/57/python-ping-subnet.html?to my system but received the same error when I ran it.?
You can see the error screenshot here:?https://unsee.cc/sonezima/?Thank you. 

? ? On Saturday, April 30, 2016 11:12 PM, Steven D'Aprano <steve at pearwood.info> wrote:
 
 

 On Sat, Apr 30, 2016 at 06:51:17PM +0000, Jason N. via Tutor wrote:
> Hello,
> I found this simple script online but when I execute it I get the 
> following error: "TypeError: 'list' object is not callable" Here is 
> the code sample:
>
> import subprocess
> ls_output= subprocess.check_output(['dir'])

The code snippet works fine.

Please check that the code you send is exactly the same as the code you 
are actually trying to run. Do not just retype the code from memory, 
copy and paste it.

Also, please copy and paste the full traceback that you get, not just 
the final error message. Everything from the first "Traceback" line to 
the end.

Finally, you should tell us what version of Python you are running, on 
what operating system (Linux, Mac OS, Windows XP, Windows 10, Android, 
something else), and whether you are using the standard Python 
interactive interpreter or something else (IDLE, iPython, Anaconda, 
PyCharm, etc.).


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


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


 
  

From nymcity at yahoo.com  Mon May  2 17:26:54 2016
From: nymcity at yahoo.com (Jason N.)
Date: Mon, 2 May 2016 21:26:54 +0000 (UTC)
Subject: [Tutor] Dictionary Question
References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com>
Message-ID: <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com>

Hello,
Wanted to ask if its possible to have a dictionary that can be looked up by either values?
For example,?
mydic = {"A: "Apple", "B": "Banana"}When user inputs "A" I want "Apple" to come. But if the user enter "Apple" I want "A" to respond.
Please let me know the best way to handle this type cause instead of just created duplicate entries to cover all possibilities.?Thank you.

From itetteh34 at hotmail.com  Mon May  2 17:55:29 2016
From: itetteh34 at hotmail.com (isaac tetteh)
Date: Mon, 2 May 2016 16:55:29 -0500
Subject: [Tutor] Dictionary Question
In-Reply-To: <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com>
References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com>
 <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <DUB407-EAS413EB4A2A8DD1A2AF6776B5BD790@phx.gbl>


For some reason i cant find reply all . But try this 
for key, value in mydic.items():
      If A==value:
           Print key
Nb: use iteritems() if using python2

Sent from my iPhone

> On May 2, 2016, at 4:29 PM, Jason N. via Tutor <tutor at python.org> wrote:
> 
> Hello,
> Wanted to ask if its possible to have a dictionary that can be looked up by either values?
> For example, 
> mydic = {"A: "Apple", "B": "Banana"}When user inputs "A" I want "Apple" to come. But if the user enter "Apple" I want "A" to respond.
> Please let me know the best way to handle this type cause instead of just created duplicate entries to cover all possibilities. Thank you.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From itetteh34 at hotmail.com  Mon May  2 18:01:25 2016
From: itetteh34 at hotmail.com (isaac tetteh)
Date: Mon, 2 May 2016 17:01:25 -0500
Subject: [Tutor] Dictionary Question
In-Reply-To: <DUB407-EAS413EB4A2A8DD1A2AF6776B5BD790@phx.gbl>
References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com>
 <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com>
 <DUB407-EAS413EB4A2A8DD1A2AF6776B5BD790@phx.gbl>
Message-ID: <DUB407-EAS295FEC821C8F07E5196E908BD790@phx.gbl>

Sorry for the if statement the correct statement should be "if 'apple' ==value:"

Sent from my iPhone

> On May 2, 2016, at 4:58 PM, isaac tetteh <itetteh34 at hotmail.com> wrote:
> 
> 
> For some reason i cant find reply all . But try this 
> for key, value in mydic.items():
>      If A==value:
>           Print key
> Nb: use iteritems() if using python2
> 
> Sent from my iPhone
> 
>> On May 2, 2016, at 4:29 PM, Jason N. via Tutor <tutor at python.org> wrote:
>> 
>> Hello,
>> Wanted to ask if its possible to have a dictionary that can be looked up by either values?
>> For example, 
>> mydic = {"A: "Apple", "B": "Banana"}When user inputs "A" I want "Apple" to come. But if the user enter "Apple" I want "A" to respond.
>> Please let me know the best way to handle this type cause instead of just created duplicate entries to cover all possibilities. Thank you.
>> _______________________________________________
>> 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 murarkakanika at gmail.com  Mon May  2 11:27:51 2016
From: murarkakanika at gmail.com (Kanika Murarka)
Date: Mon, 2 May 2016 20:57:51 +0530
Subject: [Tutor] Detect the folder of a file
In-Reply-To: <nfthq0$m0q$1@ger.gmane.org>
References: <CAHuvAR=LGaNgNoDH7CK14xKwAoAkMNSZ_J3fif1QGeqoutsZhw@mail.gmail.com>
 <CAGZAPF7CPWdXvynhYoNXkvpFKoiBZ-VuHt7gXSJMmGop0Ajd5w@mail.gmail.com>
 <CAHuvARmc8uZsesk63MMvpTiMsNWey0tg=fzhhT6z-Fs_YezPaw@mail.gmail.com>
 <CAHuvARnki3vehHkuoaC3LEmSwC+Pjnmx=p6PcAiiRt7jpbA2cg@mail.gmail.com>
 <CAGZAPF526knxpjpsxRwrev-NxsDEmnpwi+GQ6t5pLfmD7UZm8A@mail.gmail.com>
 <CAG5Cgtom6ddhYTRJmzXGKyM54KJ54vijqsNnnMtk5in8Wfucyw@mail.gmail.com>
 <6553cfb329696cf0af811372403c575a@sonic.net>
 <CAHuvARkaz3bZYeTXiX_JfTagD=ivN+5JTt8HOJT17kJ=zGazOA@mail.gmail.com>
 <CAHVvXxSRcf96hq7tX7xqD8EmvZESCWNkTfp7mpB-h+VMNAFrCQ@mail.gmail.com>
 <20160428101156.GS13497@ando.pearwood.info>
 <nfthq0$m0q$1@ger.gmane.org>
Message-ID: <CAHuvAR=k3ZqAQnvaTssKYOUHQ7BSfiiO_B1ZcTircjMPgYMNZQ@mail.gmail.com>

Thank you everyone !

My situation was to check the indentation of every python file via a script.
I think looking for bin/activate will work.

On 28 April 2016 at 23:08, Alan Gauld via Tutor <tutor at python.org> wrote:

> On 28/04/16 11:11, Steven D'Aprano wrote:
>
> > You know, some day I must learn why people use virtual environments.
>
> Me too :-)
>
> My co-author included a section in one of her chapters of our
> recent book, and I duly played with them while reviewing that
> chapter. But at the end I just deleted it all and
> thought "Hmmmm....?"
>
> I know why they are useful in theory, but I've never found
> a practical use for them myself.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>

From alan.gauld at yahoo.co.uk  Mon May  2 18:39:18 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 2 May 2016 23:39:18 +0100
Subject: [Tutor] Dictionary Question
In-Reply-To: <DUB407-EAS413EB4A2A8DD1A2AF6776B5BD790@phx.gbl>
References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com>
 <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com>
 <DUB407-EAS413EB4A2A8DD1A2AF6776B5BD790@phx.gbl>
Message-ID: <ng8kul$6gv$1@ger.gmane.org>

On 02/05/16 22:55, isaac tetteh wrote:
> 
> For some reason i cant find reply all . But try this 
> for key, value in mydic.items():
>       If A==value:
>            Print key

or as a function:

def findKey(dct, val):
   for k,v in dct.items():
      if v == val:
         return k

mydic = {"A: "Apple", "B": "Banana"}

print( findKey(mydic,'Apple') )   # -> 'A'

The problem is that while keys are unique, values
might not be, so what do you do if multiple keys
share the same value?

You could use a comprehension:

def findKeys(dct,val):
    keys = [k for k,v in dct.items() if v == val]
    return keys

But if you are only interested in one of them then
it's down to you to figure out which!

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



From bgailer at gmail.com  Mon May  2 18:57:53 2016
From: bgailer at gmail.com (Bob Gailer)
Date: Mon, 2 May 2016 18:57:53 -0400
Subject: [Tutor] Dictionary Question
In-Reply-To: <CAP1rxO5fbsY=2GDKjmRTi8M5Cf_pgBKUw7FCvBNfCpJN5MZd1A@mail.gmail.com>
References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com>
 <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com>
 <CAP1rxO5fbsY=2GDKjmRTi8M5Cf_pgBKUw7FCvBNfCpJN5MZd1A@mail.gmail.com>
Message-ID: <CAP1rxO60XW9kJM7CVR8G+EOXXp7-oQ_9UvMQ7honO6tqsLK7Ng@mail.gmail.com>

On May 2, 2016 5:27 PM, "Jason N. via Tutor" <tutor at python.org> wrote:
>
> Hello,
> Wanted to ask if its possible to have a dictionary that can be looked up
by either values?
> For example,
> mydic = {"A: "Apple", "B": "Banana"}When user inputs "A" I want "Apple"
to come. But if the user enter "Apple" I want "A" to respond.
I think this would depend on how big the data set is and how often you want
to look things up.
Two other Solutions:
Create a class which internally manages two dictionaries.
If things are really big create a database using for example sqlite.

From nymcity at yahoo.com  Mon May  2 20:56:56 2016
From: nymcity at yahoo.com (Jason N.)
Date: Tue, 3 May 2016 00:56:56 +0000 (UTC)
Subject: [Tutor] Dictionary Question
In-Reply-To: <CAP1rxO60XW9kJM7CVR8G+EOXXp7-oQ_9UvMQ7honO6tqsLK7Ng@mail.gmail.com>
References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com>
 <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com>
 <CAP1rxO5fbsY=2GDKjmRTi8M5Cf_pgBKUw7FCvBNfCpJN5MZd1A@mail.gmail.com>
 <CAP1rxO60XW9kJM7CVR8G+EOXXp7-oQ_9UvMQ7honO6tqsLK7Ng@mail.gmail.com>
Message-ID: <488374863.5194217.1462237016676.JavaMail.yahoo@mail.yahoo.com>

Thank you all for your responses.?
A quick follow up, what is the best way to make dictionary requests case in-sensitive? For example, "Apple and "apple" should bring back the same dictionary response.?Thank you. 

    On Monday, May 2, 2016 6:57 PM, Bob Gailer <bgailer at gmail.com> wrote:
 
 

 
On May 2, 2016 5:27 PM, "Jason N. via Tutor" <tutor at python.org> wrote:
>
> Hello,
> Wanted to ask if its possible to have a dictionary that can be looked up by either values?
> For example,?
> mydic = {"A: "Apple", "B": "Banana"}When user inputs "A" I want "Apple" to come. But if the user enter "Apple" I want "A" to respond.
I think this would depend on how big the data set is and how often you want to look things up.
Two other Solutions: 
Create a class which internally manages two dictionaries.
If things are really big create a database using for example sqlite.

 
  

From itetteh34 at hotmail.com  Mon May  2 21:18:03 2016
From: itetteh34 at hotmail.com (isaac tetteh)
Date: Mon, 2 May 2016 20:18:03 -0500
Subject: [Tutor] Dictionary Question
In-Reply-To: <488374863.5194217.1462237016676.JavaMail.yahoo@mail.yahoo.com>
References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com>
 <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com>
 <CAP1rxO5fbsY=2GDKjmRTi8M5Cf_pgBKUw7FCvBNfCpJN5MZd1A@mail.gmail.com>
 <CAP1rxO60XW9kJM7CVR8G+EOXXp7-oQ_9UvMQ7honO6tqsLK7Ng@mail.gmail.com>
 <488374863.5194217.1462237016676.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <DUB407-EAS60138E7BDC88450AD7644DBD7A0@phx.gbl>

If only I understand what you mean. You can just make all the values in the dictionary lower, upper or capitalized. Then if you want take an input or whatever you want to do with it just use .lower() or .upper() or .capitalized() to convert it to what is in the dictionary. Maybe someone has a better way to do it :) 


Sent from my iPhone

> On May 2, 2016, at 7:59 PM, Jason N. via Tutor <tutor at python.org> wrote:
> 
> Thank you all for your responses. 
> A quick follow up, what is the best way to make dictionary requests case in-sensitive? For example, "Apple and "apple" should bring back the same dictionary response. Thank you. 
> 
>    On Monday, May 2, 2016 6:57 PM, Bob Gailer <bgailer at gmail.com> wrote:
> 
> 
> 
> 
>> On May 2, 2016 5:27 PM, "Jason N. via Tutor" <tutor at python.org> wrote:
>> 
>> Hello,
>> Wanted to ask if its possible to have a dictionary that can be looked up by either values?
>> For example, mydic = {"A: "Apple", "B": "Banana"}
>> When user inputs "A" I want "Apple" to come. But if the user enter "Apple" I want "A" to respond.
> I think this would depend on how big the data set is and how often you want to look things up.
> Two other Solutions: 
> Create a class which internally manages two dictionaries.
> If things are really big create a database using for example sqlite.
> 
> 
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From cs at zip.com.au  Mon May  2 21:35:43 2016
From: cs at zip.com.au (cs at zip.com.au)
Date: Tue, 3 May 2016 11:35:43 +1000
Subject: [Tutor] Dictionary Question
In-Reply-To: <488374863.5194217.1462237016676.JavaMail.yahoo@mail.yahoo.com>
References: <488374863.5194217.1462237016676.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <20160503013543.GA62495@cskk.homeip.net>

On 03May2016 00:56, Jason N. <nymcity at yahoo.com> wrote:
>Thank you all for your responses.?
>A quick follow up, what is the best way to make dictionary requests case 
>in-sensitive? For example, "Apple and "apple" should bring back the same 
>dictionary response.?Thank you.

There are a few ways depending what your more fine grained objectives are. But 
they all tend to revolve around "normalising" the keys, which is a common 
practice for many things where multiple values are considered the same: in your 
case upper and lower case.

So the easy thing is to always convert to lower case (or upper case, but lower 
case is less SHOUTY). Eg:

  def save(d, key, value):
    d[key.lower()] = value

so the normalising function here is d.lower.

Usually you'd be making yourself a mapping class of some kind: an object which 
behaves like a dictionay:

  https://docs.python.org/3/glossary.html#term-mapping

And internally it would usually have a dictionary for storage. Completely 
untested example code:

  class CaseInsensitiveMapping:

    def __init__(self):
      self._d = {}

    def __getitem__(self, key):
      return self._d[key.lower()]
    
    def __setitem__(self, key, value):
      self._d[key.lower()] = value

and so forth for the other special ("dunder" in Pythonspeak) methods used to 
implement a mapping:

  https://docs.python.org/3/reference/datamodel.html#emulating-container-types

From the outside:

  cimap = CaseInsensitiveMapping()
  cimap['X']=1
  print(cimap['x'])

should print 1.

Now having sketched a trivial example like this, you might need to be more 
elaborate depending on youruse case. For example, some mappings like this one 
preserve the case used to insert the original key. So while ['X'] and ['x'] 
would both find the value 1, they .keys() method with recite 'X' because that 
was the specific string used to put the 1 into the mapping. That would make the 
internal implementation more complicated.

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

From dyoo at hashcollision.org  Mon May  2 21:54:22 2016
From: dyoo at hashcollision.org (Danny Yoo)
Date: Mon, 2 May 2016 18:54:22 -0700
Subject: [Tutor] simple regex question
In-Reply-To: <CAP16ngpnMJdfGdm9UObiDyaAEEN1CQcFZRmDugDQVTQi522D9Q@mail.gmail.com>
References: <CAP16ngpnMJdfGdm9UObiDyaAEEN1CQcFZRmDugDQVTQi522D9Q@mail.gmail.com>
Message-ID: <CAGZAPF4o9a4bWJP66L6uMOKqz4regPwbsWw16PfyYD7NK_Lhew@mail.gmail.com>

On Sun, May 1, 2016 at 9:49 AM, bruce <badouglas at gmail.com> wrote:

> I've created a test regex. However, after spending time/google.. can't
> quite figure out how to then get the "complete" line containing the
> returned regex/pattern.
>
> Pretty sure this is simple, and i'm just missing something.


A few people have mentioned "beautiful soup"; I agree: you should look
into using that instead of regular expressions alone.

The docs for beautiful soup are pretty good, and should help you on your way:

    https://www.crummy.com/software/BeautifulSoup/bs4/doc/

This is not to say that regular expressions are useless.  Far from it!
 You can tell beautiful soup to search with regexes:

    https://www.crummy.com/software/BeautifulSoup/bs4/doc/#a-regular-expression
    https://www.crummy.com/software/BeautifulSoup/bs4/doc/#find-all

For your case, you can probably say something like:

    soup.find_all(id=pattern)

where the pattern is precisely the regex in your original program.
You can then get the results back as structured portions of the HTML
tree.  The point is that if you use a parser that understands HTML,
you can do table-row-oriented things without having to worry about the
actual string lines.


That's often a much better situation than trying to deal with a flat
string and trying to use regular expressions to parse tree structure.
You do not want to write code that contributes to the summoning of the
Nameless One.  (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454,
http://blog.codinghorror.com/parsing-html-the-cthulhu-way/)

From dyoo at hashcollision.org  Mon May  2 22:01:59 2016
From: dyoo at hashcollision.org (Danny Yoo)
Date: Mon, 2 May 2016 19:01:59 -0700
Subject: [Tutor] Python Homework
In-Reply-To: <85zisago5u.fsf@benfinney.id.au>
References: <CA+KwKjp6XH1Ue4y9WVb0a7GqXJURgzD+haJZckF8WLFYBH4+hA@mail.gmail.com>
 <85zisago5u.fsf@benfinney.id.au>
Message-ID: <CAGZAPF6drnEvamahAUiSf4N2h+27-d+=LG1=r+gbNZqt6gYNow@mail.gmail.com>

On Sun, May 1, 2016 at 1:47 AM, Ben Finney <ben+python at benfinney.id.au> wrote:
> Katie Tuite <katuite13 at gmail.com> writes:
>
> You'll need to write only plain text email (no attached documents, no
> ?rich text?) for the information to survive correctly. This is always
> good practice for any technical discussion forum.

Hi Katie,

Also, try to present as much background as possible.  In particular:
were there other homework problems that you were able to solve
successfully?  And for the problem you're showing us: was it all
greek, or did certain parts make sense?  Were there particular
problem-solving strategies that you tried that didn't work out?

The more you can say and verbalize, that might help to pinpoint the
confusion.  With that, we'll try to tailor our answers for you rather
than the problem specifically.


Good luck!

From crusier at gmail.com  Tue May  3 05:09:20 2016
From: crusier at gmail.com (Crusier)
Date: Tue, 3 May 2016 17:09:20 +0800
Subject: [Tutor] sqlite
Message-ID: <CAC7HCj9+EC4s3ityBhNe62LpAk6YfJs_sAahj8xLt9bbgMrBbg@mail.gmail.com>

Dear All,

I am just wondering if there is any good reference which I can learn how to
program SQLITE using Python

I can not find any book is correlated to Sqlite using Python.

Thank you

Regards,
Hank

From bharathks123 at yahoo.com  Tue May  3 06:31:19 2016
From: bharathks123 at yahoo.com (bharath ks)
Date: Tue, 3 May 2016 10:31:19 +0000 (UTC)
Subject: [Tutor] Dictionary Question
In-Reply-To: <488374863.5194217.1462237016676.JavaMail.yahoo@mail.yahoo.com>
References: <488374863.5194217.1462237016676.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <632827053.4854423.1462271479603.JavaMail.yahoo@mail.yahoo.com>

Hello,

Using iteritems would be much easier approach
Something like this
mydic = {"A": "Apple", "B": "Banana"}
for key, value in mydic.iteritems():? ? if value == "Apple":? ? ? ? print key








?Thanks & BR, Bharath Shetty 

    On Tuesday, 3 May 2016 2:57 AM, Jason N. via Tutor <tutor at python.org> wrote:
 

 Thank you all for your responses.?
A quick follow up, what is the best way to make dictionary requests case in-sensitive? For example, "Apple and "apple" should bring back the same dictionary response.?Thank you. 

? ? On Monday, May 2, 2016 6:57 PM, Bob Gailer <bgailer at gmail.com> wrote:
 
 

 
On May 2, 2016 5:27 PM, "Jason N. via Tutor" <tutor at python.org> wrote:
>
> Hello,
> Wanted to ask if its possible to have a dictionary that can be looked up by either values?
> For example,?
> mydic = {"A: "Apple", "B": "Banana"}When user inputs "A" I want "Apple" to come. But if the user enter "Apple" I want "A" to respond.
I think this would depend on how big the data set is and how often you want to look things up.
Two other Solutions: 
Create a class which internally manages two dictionaries.
If things are really big create a database using for example sqlite.

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


  

From alan.gauld at yahoo.co.uk  Tue May  3 11:40:17 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 3 May 2016 16:40:17 +0100
Subject: [Tutor] sqlite
In-Reply-To: <CAC7HCj9+EC4s3ityBhNe62LpAk6YfJs_sAahj8xLt9bbgMrBbg@mail.gmail.com>
References: <CAC7HCj9+EC4s3ityBhNe62LpAk6YfJs_sAahj8xLt9bbgMrBbg@mail.gmail.com>
Message-ID: <ngagp1$8a3$1@ger.gmane.org>

On 03/05/16 10:09, Crusier wrote:

> I am just wondering if there is any good reference which I can learn how to
> program SQLITE using Python
> 
> I can not find any book is correlated to Sqlite using Python.

You can try my tutorial below.

http://www.alan-g.me.uk/tutor/tutdbms.htm

If you want very similar information in book form then
our book 'Python Projects' contains a chapter on databases,
half of which is SQLite based.

If you want a good book on SQLite itself I can recommend:

Using SQLIte by Kreibich.

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



From bgailer at gmail.com  Tue May  3 14:01:26 2016
From: bgailer at gmail.com (bob gailer)
Date: Tue, 3 May 2016 14:01:26 -0400
Subject: [Tutor] Python Homework CORRECTION rules -> tools (programs)
In-Reply-To: <CA+KwKjr=cyzBJqvzW8O7ZgXmDibuPjUkfj6uoY3r0pTbobcaBw@mail.gmail.com>
References: <CA+KwKjp6XH1Ue4y9WVb0a7GqXJURgzD+haJZckF8WLFYBH4+hA@mail.gmail.com>
 <CAP1rxO4zawsiiAa8ZgLfm8hBS=RdN9jM-b+ApaeoK5yvq8bBgg@mail.gmail.com>
 <CA+KwKjr=cyzBJqvzW8O7ZgXmDibuPjUkfj6uoY3r0pTbobcaBw@mail.gmail.com>
Message-ID: <5728E776.2020601@gmail.com>


On May 3, 2016 3:04 AM, "Katie Tuite" <katuite13 at gmail.com 
<mailto:katuite13 at gmail.com>> wrote:
 >
 > So the question is:
 >
 > "a contour plot is a graphic representation of the relationships 
among three numeric variables in two dimensions. Two variables are for X 
and Y axes, and a third variable Z is for contour levels. The contour 
levels are plotted as curves; the area between curves can be color coded 
to indicate interpolated values.
 >
 > A color gradient specifies a range of position-dependent colors, 
usually used to fill a region.
 >
 > The class file holds data for a 1000x1000 matrix, each element is a 
floating point number and has a value between -1 and 1. Plot each point 
of the matrix using Python to a grid and assign a red to yellow color 
gradient to the plot where -1 is red and 1 is yellow."

There are two problems to be solved here. One is Computing the gradient, 
the other is displaying the graph.
Do you understand the concept of a color gradient? Do you know how to 
compute it? Have you been given any tools (programs) for displaying graphs?
Once we have that information we can take the next steps.


From michael.selik at gmail.com  Tue May  3 14:40:37 2016
From: michael.selik at gmail.com (Michael Selik)
Date: Tue, 03 May 2016 18:40:37 +0000
Subject: [Tutor] Dictionary Question
In-Reply-To: <488374863.5194217.1462237016676.JavaMail.yahoo@mail.yahoo.com>
References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com>
 <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com>
 <CAP1rxO5fbsY=2GDKjmRTi8M5Cf_pgBKUw7FCvBNfCpJN5MZd1A@mail.gmail.com>
 <CAP1rxO60XW9kJM7CVR8G+EOXXp7-oQ_9UvMQ7honO6tqsLK7Ng@mail.gmail.com>
 <488374863.5194217.1462237016676.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <CAGgTfkOaCo4rL0+Defxx9bRf85R-rGZvc8XODOiKzDzPy4otkg@mail.gmail.com>

On Mon, May 2, 2016 at 8:58 PM Jason N. via Tutor <tutor at python.org> wrote:

> What is the best way to make dictionary requests case in-sensitive? For
> example, "Apple and "apple" should bring back the same dictionary
> response. Thank you.
>

Take a look at how the requests library solves the problem with a
"CaseInsensitiveDict" (
https://github.com/kennethreitz/requests/blob/master/requests/structures.py)

From michael.selik at gmail.com  Tue May  3 14:46:17 2016
From: michael.selik at gmail.com (Michael Selik)
Date: Tue, 03 May 2016 18:46:17 +0000
Subject: [Tutor] Dictionary Question
In-Reply-To: <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com>
References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com>
 <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <CAGgTfkPzbFcb3oyECs=C-HEOeOk7XsOEbb-SJnZpg4guRDzK6A@mail.gmail.com>

On Mon, May 2, 2016 at 5:28 PM Jason N. via Tutor <tutor at python.org> wrote:

> Hello,
> Wanted to ask if its possible to have a dictionary that can be looked up
> by either values?
> For example,
> mydic = {"A: "Apple", "B": "Banana"}When user inputs "A" I want "Apple" to
> come. But if the user enter "Apple" I want "A" to respond.
> Please let me know the best way to handle this type cause instead of just
> created duplicate entries to cover all possibilities. Thank you.
>

A dictionary enforces that the keys are unique, but many keys may have the
same value. Do you want to enforce that values are unique? If not, does it
matter which key is returned if many keys have the same value?

From crusier at gmail.com  Tue May  3 20:43:40 2016
From: crusier at gmail.com (Crusier)
Date: Wed, 4 May 2016 08:43:40 +0800
Subject: [Tutor] Tutor Digest, Vol 147, Issue 10
In-Reply-To: <mailman.13.1462291201.25122.tutor@python.org>
References: <mailman.13.1462291201.25122.tutor@python.org>
Message-ID: <CAC7HCj9LgSZgSnxZJShgHZJ-amCQkjcmV+=kYfG44Eo6brHNjg@mail.gmail.com>

Thanks, Alan.

Have a great day.

Henry

On Wed, May 4, 2016 at 12:00 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: sqlite (Alan Gauld)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Tue, 3 May 2016 16:40:17 +0100
> From: Alan Gauld <alan.gauld at yahoo.co.uk>
> To: tutor at python.org
> Subject: Re: [Tutor] sqlite
> Message-ID: <ngagp1$8a3$1 at ger.gmane.org>
> Content-Type: text/plain; charset=utf-8
>
> On 03/05/16 10:09, Crusier wrote:
>
> > I am just wondering if there is any good reference which I can learn how
> to
> > program SQLITE using Python
> >
> > I can not find any book is correlated to Sqlite using Python.
>
> You can try my tutorial below.
>
> http://www.alan-g.me.uk/tutor/tutdbms.htm
>
> If you want very similar information in book form then
> our book 'Python Projects' contains a chapter on databases,
> half of which is SQLite based.
>
> If you want a good book on SQLite itself I can recommend:
>
> Using SQLIte by Kreibich.
>
> hth
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> https://mail.python.org/mailman/listinfo/tutor
>
>
> ------------------------------
>
> End of Tutor Digest, Vol 147, Issue 10
> **************************************
>

From bgailer at gmail.com  Wed May  4 10:42:13 2016
From: bgailer at gmail.com (Bob Gailer)
Date: Wed, 4 May 2016 10:42:13 -0400
Subject: [Tutor] Python Homework CORRECTION rules -> tools (programs)
In-Reply-To: <CA+KwKjo2wQDuUANV+JrMDKrKSagq5v2AzZ-1xrR8NYhquAWzUA@mail.gmail.com>
References: <CA+KwKjp6XH1Ue4y9WVb0a7GqXJURgzD+haJZckF8WLFYBH4+hA@mail.gmail.com>
 <CAP1rxO4zawsiiAa8ZgLfm8hBS=RdN9jM-b+ApaeoK5yvq8bBgg@mail.gmail.com>
 <CA+KwKjr=cyzBJqvzW8O7ZgXmDibuPjUkfj6uoY3r0pTbobcaBw@mail.gmail.com>
 <5728E776.2020601@gmail.com>
 <CA+KwKjo2wQDuUANV+JrMDKrKSagq5v2AzZ-1xrR8NYhquAWzUA@mail.gmail.com>
Message-ID: <CAP1rxO55kdO2Kk_-Oy44EJuKXvwYoj13C8mWfvnS3QLEVxHt5g@mail.gmail.com>

On May 3, 2016 2:38 PM, "Katie Tuite" <katuite13 at gmail.com> wrote:
>
> So I know what a color gradient is, I don't know how to compute it
though. As far as programs, they told us we should use matplotlib, NumPy,
and SciPy to display graphs.

Thanks. Always reply to the list as well as me.

Computing gradient. Each color has a numeric value, normally in the range
of 0 to 16,581,375. Each of your data points has a value in the range of -1
to 1. You need to get the values of  red and yellow, then the color value
of each data point is proportionately between red and yellow as the data
point is between -1 and 1.
Since I don't know your academic background I'm guessing that this
explanation might work. Let us know.
I'm not familiar enough with the plotting packages you cited. Perhaps
someone else on this list can help here.

From alan.gauld at yahoo.co.uk  Thu May  5 16:52:09 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 5 May 2016 21:52:09 +0100
Subject: [Tutor] Digest format changed to MIME
Message-ID: <nggbpo$7nj$1@ger.gmane.org>

As mentioned earlier I've changed the digest format to MIME.
If anyone has problems receiving that please let me know
offline and we'll try to resolve it.

Hopefully this will allow digest users to reply to individual
messages and avoid the frequent resending of entire digests.

It may even fix the subject line and maintain threading,
although I'm less confident on that last one.

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



From rampappula at gmail.com  Sat May  7 00:41:18 2016
From: rampappula at gmail.com (ramakrishna reddy)
Date: Fri, 6 May 2016 21:41:18 -0700
Subject: [Tutor] How to use setUpmodule() variables in tests?
Message-ID: <CAOZWNsm+T50u25icVBAH4BBzLku8o3sbush7043TjA1dZ8h3rg@mail.gmail.com>

Dear All,

In unittesting in python, how can I use variables of setUpModule() in tests?

example:

import unittest

def setUpModule():
    b = 20  #----> how can I use this variable in testa print

class A(unittest.TestCase):
    def testa(self):
        a = 10
        print(a + b)

if __name__ == '__main__':
    unittest.main()

Thanks,
Ram

From steve at pearwood.info  Sat May  7 07:02:04 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Sat, 7 May 2016 21:02:04 +1000
Subject: [Tutor] How to use setUpmodule() variables in tests?
In-Reply-To: <CAOZWNsm+T50u25icVBAH4BBzLku8o3sbush7043TjA1dZ8h3rg@mail.gmail.com>
References: <CAOZWNsm+T50u25icVBAH4BBzLku8o3sbush7043TjA1dZ8h3rg@mail.gmail.com>
Message-ID: <20160507110203.GR12028@ando.pearwood.info>

On Fri, May 06, 2016 at 09:41:18PM -0700, ramakrishna reddy wrote:
> Dear All,
> 
> In unittesting in python, how can I use variables of setUpModule() in tests?
> 
> example:
> 
> import unittest
> 
> def setUpModule():
>     b = 20  #----> how can I use this variable in testa print

b here is a local variable. If you want it to be seen outside of the 
setUpModule function, you have to make it a global variable.



-- 
Steve

From alan.gauld at yahoo.co.uk  Sun May  8 03:59:01 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 8 May 2016 08:59:01 +0100
Subject: [Tutor] META: Moderation and subscription to the tutor list
In-Reply-To: <20160501041826.GB13497@ando.pearwood.info>
References: <20160501041826.GB13497@ando.pearwood.info>
Message-ID: <ngmrk4$pen$1@ger.gmane.org>

On 01/05/16 05:18, Steven D'Aprano wrote:

> ...(And I think we should default to 
> individual emails, not daily digest.)

It took me a little while to find this one, but I've checked
and the default is to receive individual emails. You need to
opt-in to get the digests and opt-out to stop getting emails.

This means you can get
- single emails (default)
- emails plus digest
- neither (this is my choice because I read via gmane)

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



From steve at pearwood.info  Sun May  8 06:48:14 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 8 May 2016 20:48:14 +1000
Subject: [Tutor] META: Moderation and subscription to the tutor list
In-Reply-To: <ngmrk4$pen$1@ger.gmane.org>
References: <20160501041826.GB13497@ando.pearwood.info>
 <ngmrk4$pen$1@ger.gmane.org>
Message-ID: <20160508104814.GV12028@ando.pearwood.info>

On Sun, May 08, 2016 at 08:59:01AM +0100, Alan Gauld via Tutor wrote:
> On 01/05/16 05:18, Steven D'Aprano wrote:
> 
> > ...(And I think we should default to 
> > individual emails, not daily digest.)
> 
> It took me a little while to find this one, but I've checked
> and the default is to receive individual emails. You need to
> opt-in to get the digests and opt-out to stop getting emails.

Thanks for checking!

-- 
Steve

From alan.gauld at yahoo.co.uk  Sun May  8 10:42:56 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 8 May 2016 15:42:56 +0100
Subject: [Tutor] META: Moderation and subscription to the tutor list
In-Reply-To: <ngmrk4$pen$1@ger.gmane.org>
References: <20160501041826.GB13497@ando.pearwood.info>
 <ngmrk4$pen$1@ger.gmane.org>
Message-ID: <ngnj9f$9bn$1@ger.gmane.org>

On 08/05/16 08:59, Alan Gauld via Tutor wrote:

> This means you can get
> - single emails (default)
> - emails plus digest

- digest and no emails

> - neither (this is my choice because I read via gmane)

Sorry, I missed an option...


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



From hunter.t.joz at gmail.com  Sun May  8 09:07:46 2016
From: hunter.t.joz at gmail.com (Hunter Jozwiak)
Date: Sun, 8 May 2016 09:07:46 -0400
Subject: [Tutor] Best Practices with JSON Data
Message-ID: <010a01d1a92a$9dbec1e0$d93c45a0$@gmail.com>

Hello,

 

I am intending to start work on a Python program that will allow me to
better manage my Digital Ocean droplets, due to the fact that the website
can be at times a bit overkill for some of the basic tasks I want to do. I
have a question in regards to the best practice of manipulating JSON data.
Would it be better to just parse the data that Digital Ocean returns as a
result of doing such things as a Get command, or would it be better to
create a Droplet class with functionality specific to Droplets? The reason I
am asking is due to the fact that I haven't found any good information on
the topic, so am not sure of the Pythonic or standard way to do this.

 

Thanks,

 

Hunter


From dyoo at hashcollision.org  Sun May  8 16:32:58 2016
From: dyoo at hashcollision.org (Danny Yoo)
Date: Sun, 8 May 2016 13:32:58 -0700
Subject: [Tutor] Best Practices with JSON Data
In-Reply-To: <010a01d1a92a$9dbec1e0$d93c45a0$@gmail.com>
References: <010a01d1a92a$9dbec1e0$d93c45a0$@gmail.com>
Message-ID: <CAGZAPF7ORCg-R73QYOCDtmR52+i-=S+p=1--im7kHsHnoXNbYQ@mail.gmail.com>

On Sun, May 8, 2016 at 6:07 AM, Hunter Jozwiak <hunter.t.joz at gmail.com> wrote:
> Hello,
>
>
>
> I am intending to start work on a Python program that will allow me to
> better manage my Digital Ocean droplets

It sounds like you're using the DigitalOcean API described in
https://developers.digitalocean.com/documentation/v2/


> Would it be better to just parse the data that Digital Ocean returns as a
> result of doing such things as a Get command, or would it be better to
> create a Droplet class with functionality specific to Droplets?

If I understand you rightly, then either approach is arguably ok.  It
really depends on what you'll intend to do in the short/medium/long
term, and how much you already understand about the final shape of
things.

The first approach sounds like you'll take the JSON and pull just the
minimal information that you care about.  I think that, in your second
proposal, you're talking about processing everything in the JSON
response, even the stuff that you're not immediately caring about at
this moment.

I believe the question you're asking is essentially: bottom-up, or top-down?

If it's just for your own one-off usage, and no one else has done
much, I'd prefer the first, because it's going to be less work, and
you can make certain simplifying assumptions to make your program
short, since you know exactly what parts of the JSON you can ignore.

Since you are starting off, you may not necessarily know the
appropriate structure of all the classes yet.  Rather than commit to a
particular top-down design, you might want to just do the simplest
thing first, get some exposure, and then build up from that
experience.


By the way, it does look like there are some Python libraries provided
by the DigitalOcean folks: you might want to take a look at them:

    https://developers.digitalocean.com/libraries/

and perhaps you can reuse those libraries.


Good luck to you!

From michael.selik at gmail.com  Sun May  8 13:26:46 2016
From: michael.selik at gmail.com (Michael Selik)
Date: Sun, 08 May 2016 17:26:46 +0000
Subject: [Tutor] Best Practices with JSON Data
In-Reply-To: <010a01d1a92a$9dbec1e0$d93c45a0$@gmail.com>
References: <010a01d1a92a$9dbec1e0$d93c45a0$@gmail.com>
Message-ID: <CAGgTfkMY-G0T0jHm9aKd5mzWaYGh0qtuWYZz9edKfSFX68H11A@mail.gmail.com>

On Sun, May 8, 2016, 12:34 PM Hunter Jozwiak <hunter.t.joz at gmail.com> wrote:

> Hello,
>
>
>
> I am intending to start work on a Python program that will allow me to
> better manage my Digital Ocean droplets, due to the fact that the website
> can be at times a bit overkill for some of the basic tasks I want to do. I
> have a question in regards to the best practice of manipulating JSON data.
> Would it be better to just parse the data that Digital Ocean returns as a
> result of doing such things as a Get command, or would it be better to
> create a Droplet class with functionality specific to Droplets? The reason
> I
> am asking is due to the fact that I haven't found any good information on
> the topic, so am not sure of the Pythonic or standard way to do this.
>

Go the route of least complexity until you need to refactor. Start with
basic collections. Define a class later, if ever.

>

From monikajg at netzero.net  Sun May  8 13:14:44 2016
From: monikajg at netzero.net (monikajg at netzero.net)
Date: Sun, 8 May 2016 17:14:44 GMT
Subject: [Tutor] Practice python
Message-ID: <20160508.101444.16108.0@webmail13.dca.untd.com>


HI:
Can you please recommend a free web class or site that offers lots of coding  exercises in python, not just the beginning but also intermediate and advanced AND provides solutions. I need more practice. All the classes I have taken or looked at do not provide enough exercises (with solutions) to retain the info.
Thank you very much
Monika

____________________________________________________________
Scribol.com
20 Female Celebrities Who Are Totally Different in Real Life
http://thirdpartyoffers.netzero.net/TGL3241/572f744288d8074424f2est01duc

From alan.gauld at yahoo.co.uk  Sun May  8 19:46:47 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 9 May 2016 00:46:47 +0100
Subject: [Tutor] Best Practices with JSON Data
In-Reply-To: <010a01d1a92a$9dbec1e0$d93c45a0$@gmail.com>
References: <010a01d1a92a$9dbec1e0$d93c45a0$@gmail.com>
Message-ID: <ngoj55$iss$1@ger.gmane.org>

On 08/05/16 14:07, Hunter Jozwiak wrote:

> I am intending to start work on a Python program that will allow me to
> better manage my Digital Ocean droplets, due to the fact that the website
> can be at times a bit overkill for some of the basic tasks I want to do. 

OK, but I have absolutely no idea what Digital ocean is, nor
what a droplet is. So we may need more background later.

> have a question in regards to the best practice of manipulating JSON data.
> Would it be better to just parse the data that Digital Ocean returns as a
> result of doing such things as a Get command, or would it be better to
> create a Droplet class with functionality specific to Droplets? 

That really depends on what you plan on doing.
If you need to do a lot of processing of the data or using it
in interaction with other objects/data then a class might make
sense.  But if you just want to collect data into a data store
(file or dbms) or filter out some reports then just reading
the JSON is probably fine.

> am asking is due to the fact that I haven't found any good information on
> the topic, so am not sure of the Pythonic or standard way to do this.

There's probably no information about droplets except on the Digital
Ocean forums (assuming such things exist!). But the general approach
in Python is to do whatever makes most sense. Don't over complicate
things but don't over simplify either. It all depends on what you
need to do.


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



From alan.gauld at yahoo.co.uk  Sun May  8 20:00:29 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 9 May 2016 01:00:29 +0100
Subject: [Tutor] Practice python
In-Reply-To: <20160508.101444.16108.0@webmail13.dca.untd.com>
References: <20160508.101444.16108.0@webmail13.dca.untd.com>
Message-ID: <ngojus$tm2$1@ger.gmane.org>

On 08/05/16 18:14, monikajg at netzero.net wrote:

> Can you please recommend a free web class or site that offers 
> lots of coding  exercises in python,

Have you tried the Python Challenge web site?

> ... intermediate and advanced AND provides solutions. 

The challenge site gets pretty advanced as you progress but
there is usually an easy(ish) and a hard solution and you
don't get shown a "correct" one - because correct doesn't
make any real sense - you just know you got the right
answer when you make it to the next level.

But it certainly helps you grow as a Python programmer
and it especially gets you familiar with the library.

> I need more practice. 

Often the best practice is to do.
Just pick a real project and wade in.

> All the classes I have taken or looked at do not provide 
> enough exercises (with solutions) to retain the info.

I'm always wary of "solutions". They can only ever be the
authors best attempt but there will always be other,
equally legitimate solutions. In my recent book I took
pains to make the point that the "solutions" were only
one possible way of doing it and if a reader did it
another way that was probably fine too.

I know a lot of people like exercises (and solutions)
in books and tats why I provide them, but personally
I've never done them in any programming book I've
read (and that means dozens), instead I solve my
own problems, even ones I've already solved in
other languages...

You will always learn far more from real world problem
solving than from, any artificial exercise/solution.

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



From joel.goldstick at gmail.com  Sun May  8 20:03:41 2016
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Sun, 8 May 2016 20:03:41 -0400
Subject: [Tutor] Practice python
In-Reply-To: <ngojus$tm2$1@ger.gmane.org>
References: <20160508.101444.16108.0@webmail13.dca.untd.com>
 <ngojus$tm2$1@ger.gmane.org>
Message-ID: <CAPM-O+zqSPM4imS_Dj-yaV9ifCsXYiM5skiDSgwSk2_y+PU6WA@mail.gmail.com>

I like the euler project

On Sun, May 8, 2016 at 8:00 PM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 08/05/16 18:14, monikajg at netzero.net wrote:
>
>> Can you please recommend a free web class or site that offers
>> lots of coding  exercises in python,
>
> Have you tried the Python Challenge web site?
>
>> ... intermediate and advanced AND provides solutions.
>
> The challenge site gets pretty advanced as you progress but
> there is usually an easy(ish) and a hard solution and you
> don't get shown a "correct" one - because correct doesn't
> make any real sense - you just know you got the right
> answer when you make it to the next level.
>
> But it certainly helps you grow as a Python programmer
> and it especially gets you familiar with the library.
>
>> I need more practice.
>
> Often the best practice is to do.
> Just pick a real project and wade in.
>
>> All the classes I have taken or looked at do not provide
>> enough exercises (with solutions) to retain the info.
>
> I'm always wary of "solutions". They can only ever be the
> authors best attempt but there will always be other,
> equally legitimate solutions. In my recent book I took
> pains to make the point that the "solutions" were only
> one possible way of doing it and if a reader did it
> another way that was probably fine too.
>
> I know a lot of people like exercises (and solutions)
> in books and tats why I provide them, but personally
> I've never done them in any programming book I've
> read (and that means dozens), instead I solve my
> own problems, even ones I've already solved in
> other languages...
>
> You will always learn far more from real world problem
> solving than from, any artificial exercise/solution.
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Joel Goldstick
http://joelgoldstick.com/blog
http://cc-baseballstats.info/stats/birthdays

From robertvstepp at gmail.com  Sun May  8 20:30:17 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Sun, 8 May 2016 19:30:17 -0500
Subject: [Tutor] Practice python
In-Reply-To: <20160508.101444.16108.0@webmail13.dca.untd.com>
References: <20160508.101444.16108.0@webmail13.dca.untd.com>
Message-ID: <CANDiX9+C8qOGu1PJkdhBFNxt2=BqVrJe6X6R4QZm87mAKjVbFQ@mail.gmail.com>

On Sun, May 8, 2016 at 12:14 PM, monikajg at netzero.net
<monikajg at netzero.net> wrote:

> Can you please recommend a free web class or site that offers lots of coding  exercises in python, not just the beginning but also intermediate and advanced AND provides solutions. I need more practice. All the classes I have taken or looked at do not provide enough exercises (with solutions) to retain the info.

You might look into the MIT Open Courseware.  Once you get into the
meat of the material the programming exercises get increasingly
challenging.  There are also copies of exams, quizzes, etc.  However,
if memory serves me correctly, they may still be using Python 2.
Also, you can poke around in both their electrical engineering and
computer science departments.  Sometimes they cover the same type of
material at different paces and levels of difficulty.  Stanford also
has some courses, but the last time I went looking there I was
checking out Java.  Anyway, one MIT link is:

http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00sc-introduction-to-computer-science-and-programming-spring-2011/index.htm


-- 
boB

From lwaters at flinthill.org  Mon May  9 07:59:36 2016
From: lwaters at flinthill.org (Lisa Hasler Waters)
Date: Mon, 9 May 2016 07:59:36 -0400
Subject: [Tutor] How to make object disappear?
Message-ID: <CAF91wy-dd2U-9gTumU+=YvEVz0ZPrxopzLLRHmYdLoe9tr1c4w@mail.gmail.com>

Dear Tutor,

My students and I are creating a maze game in tkinter. We are trying to
make the ball disappear when it hits the wall (black lines). We are not
having much luck. The following code has run the best, but still, the ball
does not disappear. Any advice would be appreciated!

from tkinter import *
import random
import time


tk = Tk()
tk.title("Game")
tk.resizable(0, 0)
tk.wm_attributes("-topmost", 1)
canvas = Canvas(tk, width=1400, height=835, bd=0, highlightthickness=0)
canvas.pack()
tk.update()


class dot:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_oval(15, 15, 30, 30, fill='Blue',
tags='dot1')

this = dot(canvas, 'blue')

def ball(n, x, y):
    canvas.move(n, x, y)

def mt(event):
            if event.keysym == 'Left':
                ball(1, -30, 0)
                restart()
            elif event.keysym == 'Up':
                ball(1, 0, -30)
                restart()
            elif event.keysym == 'Down':
                ball(1, 0, 30)
                restart()
            elif event.keysym == 'Right':
                ball(1, 30, 0)
                restart()
            else:
                ball(1, 30, 0)
                restart()

canvas.bind_all('<KeyPress-Up>', mt)
canvas.bind_all('<KeyPress-Down>', mt)
canvas.bind_all('<KeyPress-Left>', mt)
canvas.bind_all('<KeyPress-Right>', mt)

dot_bbox = canvas.coords('dot1')




x = dot_bbox[0]
y = dot_bbox[1]
x2 = dot_bbox[2]
y2 = dot_bbox[3]

canvas.create_line(0, 0, 0, 300, width=20)
canvas.create_line(0, 300, 300, 300, width=10)
canvas.create_line(80, 240, 80, 0, width=10)
canvas.create_line(160, 300, 160, 60, width=10)
canvas.create_line(240, 240, 240, 0, width=10)
canvas.create_line(300, 300, 300, 150, width=10)
canvas.create_line(300, 150, 600, 150, width=10)
canvas.create_line(80, 0, 2000, 0, width=30)
canvas.create_line(300, 75, 600, 75, width=10)
canvas.create_line(760, 0, 760, 300, width=10)
canvas.create_line(600, 75, 680, 75, width=10)

def restart():
    if (canvas.find_overlapping(x, y, x2, y2) == (1, 2)) or
(canvas.find_overlapping(x, y, x2, y2) == (1, 3)) or
(canvas.find_overlapping(x, y, x2, y2) == (1, 4)) or
(canvas.find_overlapping(x, y, x2, y2) == (1, 5)) or
(canvas.find_overlapping(x, y, x2, y2) == (1, 6)) == True:
        canvas.delete('dot1')






Shell:

Python 3.5.1 (v3.5.1:37a07cee5969, Dec  5 2015, 21:12:44)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>> 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.

>>>
================ RESTART: /Users/BScherer/Desktop/MazeTest.py
================
>>>
=============================== RESTART: Shell
===============================
>>>
================ RESTART: /Users/BScherer/Desktop/MazeTest.py
================
>>>
=============================== RESTART: Shell
===============================
>>> from tkinter import *
>>> import random
>>> import time
>>> tk = Tk()
>>>
>>> tk.title("Game")
''
>>> tk.resizable(0, 0)
''
>>> tk.wm_attributes("-topmost", 1)
''
>>> canvas = Canvas(tk, width=1400, height=835, bd=0, highlightthickness=0)
>>> canvas.pack()
>>> tk.update()
>>> class dot:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_oval(10, 10, 25, 25, fill='Blue',
tags='dot1')


>>> this = dot(canvas, 'blue')
>>> def ball(n, x, y):
    canvas.move(n, x, y)


>>> def mt(event):
            if event.keysym == 'Left':
                ball(1, -30, 0)
                restart()
            elif event.keysym == 'Up':
                ball(1, 0, -30)
                restart()
            elif event.keysym == 'Down':
                ball(1, 0, 30)
                restart()
            elif event.keysym == 'Right':
                ball(1, 30, 0)
                restart()
            else:
                ball(1, 30, 0)
                restart()


>>> canvas.bind_all('<KeyPress-Up>', mt)
'4300440008mt'
>>> canvas.bind_all('<KeyPress-Down>', mt)
'4329736584mt'
>>> canvas.bind_all('<KeyPress-Left>', mt)
'4380738824mt'
>>> canvas.bind_all('<KeyPress-Right>', mt)
'4383283336mt'
>>> dot_bbox = canvas.coords('dot1')
>>> x = dot_bbox[0]
>>> y = dot_bbox[1]
>>> x2 = dot_bbox[2]
>>> y2 = dot_bbox[3]
>>> print(canvas.find_overlapping(x, y, x2, y2))
(1,)
>>> print(canvas.find_overlapping(x, y, x2, y2))
(1,)
>>> canvas.create_line(0, 0, 0, 300, width=20)
2
>>> print(canvas.find_overlapping(x, y, x2, y2))
(1, 2)
>>> canvas.create_line(600, 75, 680, 75, width=10)
3
>>> print(canvas.find_overlapping(x, y, x2, y2))
(1, 2)
>>>
================ RESTART: /Users/BScherer/Desktop/MazeTest.py
================
>>>
=============================== RESTART: Shell
===============================
>>>
================ RESTART: /Users/BScherer/Desktop/MazeTest.py
================
>>>
=============================== RESTART: Shell
===============================
>>>
================ RESTART: /Users/BScherer/Desktop/MazeTest.py
================
>>>
=============================== RESTART: Shell
===============================
>>>
================ RESTART: /Users/BScherer/Desktop/MazeTest.py
================
>>>
================ RESTART: /Users/BScherer/Desktop/MazeTest.py
================
>>>
================ RESTART: /Users/BScherer/Desktop/MazeTest.py
================
>>>

-- 
Lisa Waters, PhD
Technology Integration
Flint Hill School

From bgailer at gmail.com  Mon May  9 10:56:04 2016
From: bgailer at gmail.com (Bob Gailer)
Date: Mon, 9 May 2016 10:56:04 -0400
Subject: [Tutor] How to make object disappear?
In-Reply-To: <CAF91wy-dd2U-9gTumU+=YvEVz0ZPrxopzLLRHmYdLoe9tr1c4w@mail.gmail.com>
References: <CAF91wy-dd2U-9gTumU+=YvEVz0ZPrxopzLLRHmYdLoe9tr1c4w@mail.gmail.com>
Message-ID: <CAP1rxO4B9iCqgJzCHsmnxQrhkL4ARBq-YKXGS3LBF5GqHfygQw@mail.gmail.com>

On May 9, 2016 8:01 AM, "Lisa Hasler Waters" <lwaters at flinthill.org> wrote:
>
> Dear Tutor,
>
> My students and I are creating a maze game in tkinter. We are trying to
> make the ball disappear when it hits the wall (black lines). We are not
> having much luck. The following code has run the best, but still, the ball
> does not disappear. Any advice would be appreciated!
>
> from tkinter import *
> import random
> import time
>
>
> tk = Tk()
> tk.title("Game")
> tk.resizable(0, 0)
> tk.wm_attributes("-topmost", 1)
> canvas = Canvas(tk, width=1400, height=835, bd=0, highlightthickness=0)
> canvas.pack()
> tk.update()
>
>
> class dot:

It is a Python convention to capitalize class names. In the future write
class Dot.

>     def __init__(self, canvas, color):
>         self.canvas = canvas
>         self.id = canvas.create_oval(15, 15, 30, 30, fill='Blue',
> tags='dot1')
>
> this = dot(canvas, 'blue')
>
> def ball(n, x, y):
>     canvas.move(n, x, y)
>
> def mt(event):
>             if event.keysym == 'Left':
>                 ball(1, -30, 0)
>                 restart()
>             elif event.keysym == 'Up':
>                 ball(1, 0, -30)
>                 restart()
>             elif event.keysym == 'Down':
>                 ball(1, 0, 30)
>                 restart()
>             elif event.keysym == 'Right':
>                 ball(1, 30, 0)
>                 restart()
>             else:
>                 ball(1, 30, 0)
>                 restart()

This is my own opinion. It is important to separate data from logic. In
this case you are trying to map a key symbol to some numeric values:
key_to_val = {'Left' : (0, 30, 0), 'Right' etc}

(I realize you are probably introducing students to programming. So you
might first show the  then else logic, then introduce the dictionary
alternative.)

val = key_to_val.get(event.keysym, (30, 0))
ball(val)
restart()

15 lines of code replaced by 4. Easier to write,  easier to understand,
easier to maintain. Worth learning about dictionaries.
>
> canvas.bind_all('<KeyPress-Up>', mt)
> canvas.bind_all('<KeyPress-Down>', mt)
> canvas.bind_all('<KeyPress-Left>', mt)
> canvas.bind_all('<KeyPress-Right>', mt)
>
> dot_bbox = canvas.coords('dot1')
>
>
>
>
> x = dot_bbox[0]
> y = dot_bbox[1]
> x2 = dot_bbox[2]
> y2 = dot_bbox[3]
>
> canvas.create_line(0, 0, 0, 300, width=20)
> canvas.create_line(0, 300, 300, 300, width=10)
> canvas.create_line(80, 240, 80, 0, width=10)
> canvas.create_line(160, 300, 160, 60, width=10)
> canvas.create_line(240, 240, 240, 0, width=10)
> canvas.create_line(300, 300, 300, 150, width=10)
> canvas.create_line(300, 150, 600, 150, width=10)
> canvas.create_line(80, 0, 2000, 0, width=30)
> canvas.create_line(300, 75, 600, 75, width=10)
> canvas.create_line(760, 0, 760, 300, width=10)
> canvas.create_line(600, 75, 680, 75, width=10)
>
> def restart():
>     if (canvas.find_overlapping(x, y, x2, y2) == (1, 2)) or
> (canvas.find_overlapping(x, y, x2, y2) == (1, 3)) or
> (canvas.find_overlapping(x, y, x2, y2) == (1, 4)) or
> (canvas.find_overlapping(x, y, x2, y2) == (1, 5)) or
> (canvas.find_overlapping(x, y, x2, y2) == (1, 6)) == True:
>         canvas.delete('dot1')

I got a syntax error from that if statement.

It seems to me (obviously?) that canvas.delete is never called. This is a
great opportunity for reaching debugging. I'd add a print function call to
show the value of the canvas.find_overlapping call.

Also a good opportunity to read the manual. canvas.find_overlapping returns
a tuple of all matching items.

It would make code reading and maintenance easier if you assign
canvas.find_overlapping(x, y, x2, y2) to a name, then refer to that name in
the logic.
Revisiting the separation of data from logic:
if canvas.find_overlapping(x, y, x2, y2) in ((1,1),(1,2) etc.)

Also avoid things like if x ==True:
It is sufficient to write if x:

In English we say "if it is raining..." rather than " if it is raining is
True ".

Take what you want -l eave the rest.
>
>
>
>
>
>
> Shell:
>
> Python 3.5.1 (v3.5.1:37a07cee5969, Dec  5 2015, 21:12:44)
> [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
> Type "copyright", "credits" or "license()" for more information.
> >>> 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.
>
> >>>
> ================ RESTART: /Users/BScherer/Desktop/MazeTest.py
> ================
> >>>
> =============================== RESTART: Shell
> ===============================
> >>>
> ================ RESTART: /Users/BScherer/Desktop/MazeTest.py
> ================
> >>>
> =============================== RESTART: Shell
> ===============================
> >>> from tkinter import *
> >>> import random
> >>> import time
> >>> tk = Tk()
> >>>
> >>> tk.title("Game")
> ''
> >>> tk.resizable(0, 0)
> ''
> >>> tk.wm_attributes("-topmost", 1)
> ''
> >>> canvas = Canvas(tk, width=1400, height=835, bd=0,
highlightthickness=0)
> >>> canvas.pack()
> >>> tk.update()
> >>> class dot:
>     def __init__(self, canvas, color):
>         self.canvas = canvas
>         self.id = canvas.create_oval(10, 10, 25, 25, fill='Blue',
> tags='dot1')
>
>
> >>> this = dot(canvas, 'blue')
> >>> def ball(n, x, y):
>     canvas.move(n, x, y)
>
>
> >>> def mt(event):
>             if event.keysym == 'Left':
>                 ball(1, -30, 0)
>                 restart()
>             elif event.keysym == 'Up':
>                 ball(1, 0, -30)
>                 restart()
>             elif event.keysym == 'Down':
>                 ball(1, 0, 30)
>                 restart()
>             elif event.keysym == 'Right':
>                 ball(1, 30, 0)
>                 restart()
>             else:
>                 ball(1, 30, 0)
>                 restart()
>
>
> >>> canvas.bind_all('<KeyPress-Up>', mt)
> '4300440008mt'
> >>> canvas.bind_all('<KeyPress-Down>', mt)
> '4329736584mt'
> >>> canvas.bind_all('<KeyPress-Left>', mt)
> '4380738824mt'
> >>> canvas.bind_all('<KeyPress-Right>', mt)
> '4383283336mt'
> >>> dot_bbox = canvas.coords('dot1')
> >>> x = dot_bbox[0]
> >>> y = dot_bbox[1]
> >>> x2 = dot_bbox[2]
> >>> y2 = dot_bbox[3]
> >>> print(canvas.find_overlapping(x, y, x2, y2))
> (1,)
> >>> print(canvas.find_overlapping(x, y, x2, y2))
> (1,)
> >>> canvas.create_line(0, 0, 0, 300, width=20)
> 2
> >>> print(canvas.find_overlapping(x, y, x2, y2))
> (1, 2)
> >>> canvas.create_line(600, 75, 680, 75, width=10)
> 3
> >>> print(canvas.find_overlapping(x, y, x2, y2))
> (1, 2)
> >>>
> ================ RESTART: /Users/BScherer/Desktop/MazeTest.py
> ================
> >>>
> =============================== RESTART: Shell
> ===============================
> >>>
> ================ RESTART: /Users/BScherer/Desktop/MazeTest.py
> ================
> >>>
> =============================== RESTART: Shell
> ===============================
> >>>
> ================ RESTART: /Users/BScherer/Desktop/MazeTest.py
> ================
> >>>
> =============================== RESTART: Shell
> ===============================
> >>>
> ================ RESTART: /Users/BScherer/Desktop/MazeTest.py
> ================
> >>>
> ================ RESTART: /Users/BScherer/Desktop/MazeTest.py
> ================
> >>>
> ================ RESTART: /Users/BScherer/Desktop/MazeTest.py
> ================
> >>>
>
> --
> Lisa Waters, PhD
> Technology Integration
> Flint Hill School
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From robertvstepp at gmail.com  Mon May  9 11:55:38 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 9 May 2016 10:55:38 -0500
Subject: [Tutor] How to make object disappear?
In-Reply-To: <CAF91wy-dd2U-9gTumU+=YvEVz0ZPrxopzLLRHmYdLoe9tr1c4w@mail.gmail.com>
References: <CAF91wy-dd2U-9gTumU+=YvEVz0ZPrxopzLLRHmYdLoe9tr1c4w@mail.gmail.com>
Message-ID: <CANDiX9KwfpcRDBNuMhFuCp_-tDFQT8M9+pV2MDZuUKbw8W_Bdw@mail.gmail.com>

Hello!

I am not one of the experts; instead, I am one of the learners.  But
if you are seeking assistance on Tutor, it is necessary to post the
actual code that you successfully or unsuccessfully ran.  If you were
unsuccessful, you need to copy and paste the full text of the error
messages you received.

On Mon, May 9, 2016 at 6:59 AM, Lisa Hasler Waters
<lwaters at flinthill.org> wrote:

The code you give below does not run when I copy and paste it into my
environment.  The indentation (Which is CRITICAL in Python.) is
inconsistent and in places wrong.  It is typical to use 4 spaces for
each level of indentation.  If your email client is mangling your
indentations, then you need to determine how to correct this prior to
posting!  To see what your code looks like from my perspective, go to
https://mail.python.org/pipermail/tutor/2016-May/108832.html

> from tkinter import *
> import random
> import time
>
>
> tk = Tk()
> tk.title("Game")
> tk.resizable(0, 0)
> tk.wm_attributes("-topmost", 1)
> canvas = Canvas(tk, width=1400, height=835, bd=0, highlightthickness=0)
> canvas.pack()
> tk.update()
>
>
> class dot:
>     def __init__(self, canvas, color):
>         self.canvas = canvas
>         self.id = canvas.create_oval(15, 15, 30, 30, fill='Blue',
> tags='dot1')
>
> this = dot(canvas, 'blue')
>
> def ball(n, x, y):
>     canvas.move(n, x, y)
>
> def mt(event):
>             if event.keysym == 'Left':
>                 ball(1, -30, 0)
>                 restart()
>             elif event.keysym == 'Up':
>                 ball(1, 0, -30)
>                 restart()
>             elif event.keysym == 'Down':
>                 ball(1, 0, 30)
>                 restart()
>             elif event.keysym == 'Right':
>                 ball(1, 30, 0)
>                 restart()
>             else:
>                 ball(1, 30, 0)
>                 restart()
>
> canvas.bind_all('<KeyPress-Up>', mt)
> canvas.bind_all('<KeyPress-Down>', mt)
> canvas.bind_all('<KeyPress-Left>', mt)
> canvas.bind_all('<KeyPress-Right>', mt)
>
> dot_bbox = canvas.coords('dot1')
>
> x = dot_bbox[0]
> y = dot_bbox[1]
> x2 = dot_bbox[2]
> y2 = dot_bbox[3]
>
> canvas.create_line(0, 0, 0, 300, width=20)
> canvas.create_line(0, 300, 300, 300, width=10)
> canvas.create_line(80, 240, 80, 0, width=10)
> canvas.create_line(160, 300, 160, 60, width=10)
> canvas.create_line(240, 240, 240, 0, width=10)
> canvas.create_line(300, 300, 300, 150, width=10)
> canvas.create_line(300, 150, 600, 150, width=10)
> canvas.create_line(80, 0, 2000, 0, width=30)
> canvas.create_line(300, 75, 600, 75, width=10)
> canvas.create_line(760, 0, 760, 300, width=10)
> canvas.create_line(600, 75, 680, 75, width=10)
>
> def restart():
>     if (canvas.find_overlapping(x, y, x2, y2) == (1, 2)) or
> (canvas.find_overlapping(x, y, x2, y2) == (1, 3)) or
> (canvas.find_overlapping(x, y, x2, y2) == (1, 4)) or
> (canvas.find_overlapping(x, y, x2, y2) == (1, 5)) or
> (canvas.find_overlapping(x, y, x2, y2) == (1, 6)) == True:
>         canvas.delete('dot1')

After I corrected the indentation errors, the above code still did not
run as you omitted the statement to get everything going, that is:

tk.mainloop()

Now I can see your maze game!  It looks potentially very fun and cool.

As to your actual problem, I have not gone through your "if"
conditions, but obviously you need to accurately detect when the
"edge" of the ball collides with the nearest side of one of the walls.
If such an event happens the canvas would have to be redrawn with the
walls in place, but without the ball.  If the ball is not
disappearing, then my initial thoughts would be:

    1) Your if/elif statements are not correctly detecting the collisions.
    2) You are not actually "capturing" the collision event as the
ball moves; that is, you may not be successfully detecting the ball's
*current* coordinates.
    3) You are not correctly redrawing the window at the point where
the ball must "disappear".

There are various stylistic issues.  You and your students might want
to glance through the portions of PEP 8 similar to the Python that you
are currently coding:

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

PEP 8 is the Python style-guide, which many if not most Python coders
strive to emulate.

Good luck!

boB

From chris_roysmith at internode.on.net  Mon May  9 04:13:32 2016
From: chris_roysmith at internode.on.net (Chris Roy-Smith)
Date: Mon, 9 May 2016 18:13:32 +1000
Subject: [Tutor] is there a better way to do this?
Message-ID: <573046AC.2000401@internode.on.net>

Hi
Python 3.4 Linux (ubuntu)

This code does what I want.
curs is the result of a mysql query


data = [[" " for x in range(9)] for y in range(count)]
for (ddate, mood, walk, lag, sleep) in curs:
         data[row][0]=ddate
         data[row][1]=mood
         data[row][2]=walk
         data[row][3]=lag
         data[row][4]=sleep
         row +=1


While I don't know a better way to do this, it seems a bit awkward, is 
there a better way?


Thank you
Chris Roy-Smith

From __peter__ at web.de  Mon May  9 12:20:30 2016
From: __peter__ at web.de (Peter Otten)
Date: Mon, 09 May 2016 18:20:30 +0200
Subject: [Tutor] How to make object disappear?
References: <CAF91wy-dd2U-9gTumU+=YvEVz0ZPrxopzLLRHmYdLoe9tr1c4w@mail.gmail.com>
Message-ID: <ngqdcf$bh0$1@ger.gmane.org>

Lisa Hasler Waters wrote:

> My students and I are creating a maze game in tkinter. We are trying to
> make the ball disappear when it hits the wall (black lines). We are not
> having much luck. The following code has run the best, but still, the ball
> does not disappear. Any advice would be appreciated!

You need to consider not just the ball, but the whole trajectory. When you 
can only move up/down/left/right that is roughly the rectangle spread by the 
starting and the end position of the ball. 

I calculate that rectangle as (x0,y0)-(x1,y1) in the checked_move() method 
below. I recommend that you use pen and paper, draw two rectangular "balls" 
on a horizontal or vertical line and the rectangle between them to try it 
yourself before you take a look.

I then use that rectangle to find overlapping canvas items. Of course the 
ball will always overlap with itself, so I have to make sure to rule that 
out. 

While dabbling with the code I have also cleaned it up a bit -- but you 
should still recognize it ;)


from tkinter import *
import random
import time


class Ball:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_oval(
            15, 15, 30, 30,
            fill='Blue')

    def checked_move(self, dx, dy):
        """Move unless we would hit a wall"""
        x0, y0, x1, y1 = self.canvas.coords(self.id)
        if dx > 0:
            x1 += dx
        else:
            x0 += dx
        if dy > 0:
            y1 += dy
        else:
            y0 += dy
        for id in self.canvas.find_overlapping(x0, y0, x1, y1):
            if id != self.id:
                # we will hit something other than ourselves
                # jump back to the start instead of
                # deleting ourselves
                self.canvas.coords(self.id, 15, 15, 30, 30)
                # uncomment line below if you insist on deletion
                # self.canvas.delete(self.id)
                return
        self.canvas.move(self.id, dx, dy)


def mt(event):
    STEP = 15
    if event.keysym == 'Left':
        ball.checked_move(-STEP, 0)
    elif event.keysym == 'Up':
        ball.checked_move(0, -STEP)
    elif event.keysym == 'Down':
        ball.checked_move(0, STEP)
    elif event.keysym == 'Right':
        ball.checked_move(STEP, 0)


WALLS = [
    (0, 0, 0, 300, 20),
    (0, 300, 300, 300, 10),
    (80, 240, 80, 0, 10),
    (160, 300, 160, 60, 10),
    (240, 240, 240, 0, 10),
    (300, 300, 300, 150, 10),
    (300, 150, 600, 150, 10),
    (80, 0, 2000, 0, 30),
    (300, 75, 600, 75, 10),
    (760, 0, 760, 300, 10),
    (600, 75, 680, 75, 10),
]


def main():
    global ball  # needed for mt()

    tk = Tk()
    tk.title("Game")
    tk.resizable(0, 0)
    tk.wm_attributes("-topmost", 1)
    canvas = Canvas(tk, width=1400, height=835, bd=0, highlightthickness=0)
    canvas.pack()

    ball = Ball(canvas, 'blue')

    canvas.bind_all('<KeyPress-Up>', mt)
    canvas.bind_all('<KeyPress-Down>', mt)
    canvas.bind_all('<KeyPress-Left>', mt)
    canvas.bind_all('<KeyPress-Right>', mt)

    for wall in WALLS:
        coords = wall[:4]
        width = wall[4]
        canvas.create_line(*coords, width=width, tags="wall")

    tk.mainloop()


if __name__ == "__main__":
    main()



From alan.gauld at yahoo.co.uk  Mon May  9 12:34:33 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 9 May 2016 17:34:33 +0100
Subject: [Tutor] How to make object disappear?
In-Reply-To: <CANDiX9KwfpcRDBNuMhFuCp_-tDFQT8M9+pV2MDZuUKbw8W_Bdw@mail.gmail.com>
References: <CAF91wy-dd2U-9gTumU+=YvEVz0ZPrxopzLLRHmYdLoe9tr1c4w@mail.gmail.com>
 <CANDiX9KwfpcRDBNuMhFuCp_-tDFQT8M9+pV2MDZuUKbw8W_Bdw@mail.gmail.com>
Message-ID: <ngqe6o$q3r$1@ger.gmane.org>

On 09/05/16 16:55, boB Stepp wrote:

>> class dot:
>>     def __init__(self, canvas, color):
>>         self.canvas = canvas
>>         self.id = canvas.create_oval(15, 15, 30, 30, fill='Blue',
>>                                      tags='dot1')
>>
>> this = dot(canvas, 'blue')

You create an instance of your class called this.
But you never refer to it again.

>> def ball(n, x, y):
>>     canvas.move(n, x, y)
>>
>> def restart():
>>     if (canvas.find_overlapping(x, y, x2, y2) == (1, 2)) or
>>        (canvas.find_overlapping(x, y, x2, y2) == (1, 3)) or
>>        (canvas.find_overlapping(x, y, x2, y2) == (1, 4)) or
>>        (canvas.find_overlapping(x, y, x2, y2) == (1, 5)) or
>>        (canvas.find_overlapping(x, y, x2, y2) == (1, 6)) == True:
>>         canvas.delete('dot1')

Here you delete the shape that your object, this, drew on
the canvas but you do not delete the object. 'this' is
still there.

The normal way to do this kind of thing in a GUI program
is to have the class have a paint/draw method that makes
it visible and a hide/erase  method that makes it invisible
(by drawing itself with the background colour). You probably
need a move() method too. You can then manipulate the "dot"
(although Ball is probably a more suitable name?) by
calling move() draw() and erase() on the object itself.
You might want an isOverlapping() method too, that simply
returns a boolean. That will hide all that horrible if/else
nastiness (or even the dictionary lookup if you adopt
Bob's (excellent) option.

You then wind up with something like

ball.move(x,y)
if ball.isOverlapping(X,Y,X1,Y1):
    ball.erase()
else:
    ball.draw()

Which is a lot more readable IMHO.

A more indirect solution to your problem would be to use
pyGame to build the game where sprites etc come as standard.
But pyGame itself does not of course come as standard... :-(

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



From joel.goldstick at gmail.com  Mon May  9 12:43:44 2016
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Mon, 9 May 2016 12:43:44 -0400
Subject: [Tutor] is there a better way to do this?
In-Reply-To: <573046AC.2000401@internode.on.net>
References: <573046AC.2000401@internode.on.net>
Message-ID: <CAPM-O+zx6+h60+Kv4CMtQDTU_COVG+=YCpagdo-+dBgw0muvFg@mail.gmail.com>

On Mon, May 9, 2016 at 4:13 AM, Chris Roy-Smith
<chris_roysmith at internode.on.net> wrote:
> Hi
> Python 3.4 Linux (ubuntu)
>
> This code does what I want.
> curs is the result of a mysql query
>
>
does this work (untested)?

data = []
for stuff in curs:
           data.append(stuff)
>
> While I don't know a better way to do this, it seems a bit awkward, is there
> a better way?
>
>
> Thank you
> Chris Roy-Smith
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Joel Goldstick
http://joelgoldstick.com/blog
http://cc-baseballstats.info/stats/birthdays

From __peter__ at web.de  Mon May  9 12:50:07 2016
From: __peter__ at web.de (Peter Otten)
Date: Mon, 09 May 2016 18:50:07 +0200
Subject: [Tutor] is there a better way to do this?
References: <573046AC.2000401@internode.on.net>
Message-ID: <ngqf41$a38$1@ger.gmane.org>

Chris Roy-Smith wrote:

> Hi
> Python 3.4 Linux (ubuntu)
> 
> This code does what I want.
> curs is the result of a mysql query
> 
> 
> data = [[" " for x in range(9)] for y in range(count)]
> for (ddate, mood, walk, lag, sleep) in curs:
>          data[row][0]=ddate
>          data[row][1]=mood
>          data[row][2]=walk
>          data[row][3]=lag
>          data[row][4]=sleep
>          row +=1
> 
> 
> While I don't know a better way to do this, it seems a bit awkward, is
> there a better way?

Does `curs` give `count` records? If so:

data = [
   list(row) + [" "] * 4
   for row in curs
]


From robertvstepp at gmail.com  Mon May  9 13:04:28 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 9 May 2016 12:04:28 -0500
Subject: [Tutor] How to make object disappear?
In-Reply-To: <ngqe6o$q3r$1@ger.gmane.org>
References: <CAF91wy-dd2U-9gTumU+=YvEVz0ZPrxopzLLRHmYdLoe9tr1c4w@mail.gmail.com>
 <CANDiX9KwfpcRDBNuMhFuCp_-tDFQT8M9+pV2MDZuUKbw8W_Bdw@mail.gmail.com>
 <ngqe6o$q3r$1@ger.gmane.org>
Message-ID: <CANDiX9JVRXKUrbrPBKNx4-vnGRz95-o6T_=ntV8GtwWi+yuyhQ@mail.gmail.com>

On Mon, May 9, 2016 at 11:34 AM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 09/05/16 16:55, boB Stepp wrote:

Did not!  Lisa Hasler Waters (and her students?) wrote the code!!

[Snipped her code and Alan's comments.]

boB

From lwaters at flinthill.org  Mon May  9 13:05:36 2016
From: lwaters at flinthill.org (Lisa Hasler Waters)
Date: Mon, 9 May 2016 13:05:36 -0400
Subject: [Tutor] How to make object disappear?
In-Reply-To: <ngqe6o$q3r$1@ger.gmane.org>
References: <CAF91wy-dd2U-9gTumU+=YvEVz0ZPrxopzLLRHmYdLoe9tr1c4w@mail.gmail.com>
 <CANDiX9KwfpcRDBNuMhFuCp_-tDFQT8M9+pV2MDZuUKbw8W_Bdw@mail.gmail.com>
 <ngqe6o$q3r$1@ger.gmane.org>
Message-ID: <CAF91wy9Yn-+ezg4GAa8e-nc7m5CvdZnKzTmhbQyqX0szcL2RLw@mail.gmail.com>

Thank you all so much for your guidance! We will try these out during our
next class and will hopefully find success. We can't thank you enough for
your support!

Best, Lisa and students

On Mon, May 9, 2016 at 12:34 PM, Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 09/05/16 16:55, boB Stepp wrote:
>
> >> class dot:
> >>     def __init__(self, canvas, color):
> >>         self.canvas = canvas
> >>         self.id = canvas.create_oval(15, 15, 30, 30, fill='Blue',
> >>                                      tags='dot1')
> >>
> >> this = dot(canvas, 'blue')
>
> You create an instance of your class called this.
> But you never refer to it again.
>
> >> def ball(n, x, y):
> >>     canvas.move(n, x, y)
> >>
> >> def restart():
> >>     if (canvas.find_overlapping(x, y, x2, y2) == (1, 2)) or
> >>        (canvas.find_overlapping(x, y, x2, y2) == (1, 3)) or
> >>        (canvas.find_overlapping(x, y, x2, y2) == (1, 4)) or
> >>        (canvas.find_overlapping(x, y, x2, y2) == (1, 5)) or
> >>        (canvas.find_overlapping(x, y, x2, y2) == (1, 6)) == True:
> >>         canvas.delete('dot1')
>
> Here you delete the shape that your object, this, drew on
> the canvas but you do not delete the object. 'this' is
> still there.
>
> The normal way to do this kind of thing in a GUI program
> is to have the class have a paint/draw method that makes
> it visible and a hide/erase  method that makes it invisible
> (by drawing itself with the background colour). You probably
> need a move() method too. You can then manipulate the "dot"
> (although Ball is probably a more suitable name?) by
> calling move() draw() and erase() on the object itself.
> You might want an isOverlapping() method too, that simply
> returns a boolean. That will hide all that horrible if/else
> nastiness (or even the dictionary lookup if you adopt
> Bob's (excellent) option.
>
> You then wind up with something like
>
> ball.move(x,y)
> if ball.isOverlapping(X,Y,X1,Y1):
>     ball.erase()
> else:
>     ball.draw()
>
> Which is a lot more readable IMHO.
>
> A more indirect solution to your problem would be to use
> pyGame to build the game where sprites etc come as standard.
> But pyGame itself does not of course come as standard... :-(
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Lisa Waters, PhD
Technology Integration
Flint Hill School

From nitinchandra1 at gmail.com  Mon May  9 17:14:05 2016
From: nitinchandra1 at gmail.com (nitin chandra)
Date: Tue, 10 May 2016 02:44:05 +0530
Subject: [Tutor] postgreSQL + psycopg2
Message-ID: <CAFSKaezzv-DWfVgUJX0=6HbsH9iLYnC6KMJgrTV4FKR160V1MA@mail.gmail.com>

Hi All,

I am trying to pass a variable to the following statement :

for line1 in smallLIST1:
    design1 = line1[3]
    print design1
    nextRow=cursor1.execute("SELECT designation_name FROM designation
WHERE designation_id = %s;", (design1))
    print nextRow
    print """<tr>"""
    for row in line1:
        print """<td>"""+str(row)+"""</td>"""
    print """</tr>"""

1st "print" shows values 1 , correctly.
2nd "print" shows "None".

I am not able to pass this value, 1, as variable to the SELECT statement.

the following is 'line1'

(1, 'Vinayak', 'Salunke', '1', datetime.date(1982, 6, 6), 9871234567L,
'Tower-1,Millinium tower', 0, 1, datetime.date(2016, 5, 6),
datetime.datetime(2016, 5, 6, 22, 55, 5,
tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=330, name=None)))


On postgreSQL command this works

SELECT designation_name FROM designation WHERE designation_id = 1;

Python 2.7.6, Postgresql 9.3.7, psycopg2, apache & cgi.

A little help.

Thanks

Nitin

From rusek at gybon.cz  Mon May  9 17:03:32 2016
From: rusek at gybon.cz (=?UTF-8?Q?Ond=c5=99ej_Rusek?=)
Date: Mon, 9 May 2016 23:03:32 +0200
Subject: [Tutor] is there a better way to do this?
In-Reply-To: <573046AC.2000401@internode.on.net>
References: <573046AC.2000401@internode.on.net>
Message-ID: <5730FB24.9020801@gybon.cz>

Dne 9.5.2016 v 10:13 Chris Roy-Smith napsal(a):
> Hi
> Python 3.4 Linux (ubuntu)
>
> This code does what I want.
> curs is the result of a mysql query
>
>
> data = [[" " for x in range(9)] for y in range(count)]
> for (ddate, mood, walk, lag, sleep) in curs:
>         data[row][0]=ddate
>         data[row][1]=mood
>         data[row][2]=walk
>         data[row][3]=lag
>         data[row][4]=sleep
>         row +=1
>
if you want 'lists in list' (like your solution):

data = []
for ddate, mood, walk, lag, sleep in curs:
     data += [ [ddate, mood, walk, lag, sleep] ]

or 'tuples in list':

data = []
for ddate, mood, walk, lag, sleep in curs:
   data += [ (ddate, mood, walk, lag, sleep) ]

but for 'tuples in list'... simple:

data = []
for record in curs:
   data += [record]


-- 
S pozdravem

--
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Ondrej Rusek
GYmnazium BOzeny Nemcove, Hradec Kralove, Czech
rusek at gybon.cz, http://www.gybon.cz/~rusek
ICQ: 150366991
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-


-- 
Tato zprava byla prohledana na vyskyt viru
a nebezpecneho obsahu antivirovym systemem
MailScanner a zda se byt cista.


From __peter__ at web.de  Mon May  9 17:45:29 2016
From: __peter__ at web.de (Peter Otten)
Date: Mon, 09 May 2016 23:45:29 +0200
Subject: [Tutor] postgreSQL + psycopg2
References: <CAFSKaezzv-DWfVgUJX0=6HbsH9iLYnC6KMJgrTV4FKR160V1MA@mail.gmail.com>
Message-ID: <ngr0dq$5sj$1@ger.gmane.org>

nitin chandra wrote:

> Hi All,
> 
> I am trying to pass a variable to the following statement :
> 
> for line1 in smallLIST1:
>     design1 = line1[3]
>     print design1
>     nextRow=cursor1.execute("SELECT designation_name FROM designation
> WHERE designation_id = %s;", (design1))

Note that in the expression

(design1)

the parens have no effect:

>>> design1 = 42
>>> (design1)
42

To get a 1-tuple add a comma:

>>> (design1,)
(42,)

>     print nextRow
>     print """<tr>"""
>     for row in line1:
>         print """<td>"""+str(row)+"""</td>"""
>     print """</tr>"""
> 
> 1st "print" shows values 1 , correctly.
> 2nd "print" shows "None".
> 
> I am not able to pass this value, 1, as variable to the SELECT statement.
> 
> the following is 'line1'
> 
> (1, 'Vinayak', 'Salunke', '1', datetime.date(1982, 6, 6), 9871234567L,
> 'Tower-1,Millinium tower', 0, 1, datetime.date(2016, 5, 6),
> datetime.datetime(2016, 5, 6, 22, 55, 5,
> tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=330, name=None)))
> 
> 
> On postgreSQL command this works
> 
> SELECT designation_name FROM designation WHERE designation_id = 1;
> 
> Python 2.7.6, Postgresql 9.3.7, psycopg2, apache & cgi.
> 
> A little help.
> 
> Thanks
> 
> Nitin
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



From alan.gauld at yahoo.co.uk  Mon May  9 18:49:02 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 9 May 2016 23:49:02 +0100
Subject: [Tutor] is there a better way to do this?
In-Reply-To: <5730FB24.9020801@gybon.cz>
References: <573046AC.2000401@internode.on.net> <5730FB24.9020801@gybon.cz>
Message-ID: <ngr44s$so2$1@ger.gmane.org>

On 09/05/16 22:03, Ond?ej Rusek wrote:

> but for 'tuples in list'... simple:
> 
> data = []
> for record in curs:
>    data += [record]

Couldn't that be abbreviated to:

date = list(curs)


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



From joel.goldstick at gmail.com  Mon May  9 18:54:42 2016
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Mon, 9 May 2016 18:54:42 -0400
Subject: [Tutor] is there a better way to do this?
In-Reply-To: <ngr44s$so2$1@ger.gmane.org>
References: <573046AC.2000401@internode.on.net> <5730FB24.9020801@gybon.cz>
 <ngr44s$so2$1@ger.gmane.org>
Message-ID: <CAPM-O+x_6MGgiZLk_O9Ns54A13PO73e66No08V0ecx9-LT-1oQ@mail.gmail.com>

On Mon, May 9, 2016 at 6:49 PM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 09/05/16 22:03, Ond?ej Rusek wrote:
>
>> but for 'tuples in list'... simple:
>>
>> data = []
>> for record in curs:
>>    data += [record]
>
> Couldn't that be abbreviated to:
>
> date = list(curs)
>
I thought I nailed it earlier (and others) but this is great.  An
expressive language, python
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor



-- 
Joel Goldstick
http://joelgoldstick.com/blog
http://cc-baseballstats.info/stats/birthdays

From alan.gauld at yahoo.co.uk  Mon May  9 19:06:57 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 10 May 2016 00:06:57 +0100
Subject: [Tutor] postgreSQL + psycopg2
In-Reply-To: <CAFSKaezzv-DWfVgUJX0=6HbsH9iLYnC6KMJgrTV4FKR160V1MA@mail.gmail.com>
References: <CAFSKaezzv-DWfVgUJX0=6HbsH9iLYnC6KMJgrTV4FKR160V1MA@mail.gmail.com>
Message-ID: <ngr56g$dl0$1@ger.gmane.org>

On 09/05/16 22:14, nitin chandra wrote:

> for line1 in smallLIST1:
>     design1 = line1[3]
>     print design1
>     nextRow=cursor1.execute("SELECT designation_name FROM designation
> WHERE designation_id = %s;", (design1))
>     print nextRow
>     print """<tr>"""
>     for row in line1:
>         print """<td>"""+str(row)+"""</td>"""
>     print """</tr>"""
> 
> 1st "print" shows values 1 , correctly.

I assume you mean design1?

> 2nd "print" shows "None".

I don't know postgres API so i'll assume the %s is  the correct
marker. In SQLite we'd use ?...

Also to get the results row by row I'd expect to have
to call fetchone() on the cursor:

query = """
SELECT designation_name
FROM designation
WHERE designation_id = %s;"""

nextrow = cursor1.execute(query, (design1,)).fetchone()

But Postgres DBAPI may be different...

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



From steve at pearwood.info  Mon May  9 22:01:58 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Tue, 10 May 2016 12:01:58 +1000
Subject: [Tutor] is there a better way to do this?
In-Reply-To: <573046AC.2000401@internode.on.net>
References: <573046AC.2000401@internode.on.net>
Message-ID: <20160510020158.GZ12028@ando.pearwood.info>

On Mon, May 09, 2016 at 06:13:32PM +1000, Chris Roy-Smith wrote:

> data = [[" " for x in range(9)] for y in range(count)]
> for (ddate, mood, walk, lag, sleep) in curs:
>         data[row][0]=ddate
>         data[row][1]=mood
>         data[row][2]=walk
>         data[row][3]=lag
>         data[row][4]=sleep
>         row +=1
> 
> While I don't know a better way to do this, it seems a bit awkward, is 
> there a better way?

Hmmm, it's hard to be sure because we don't really know what count is. 
Do you want a bunch of empty rows at the end? My guess is No. 

In your code above, you initialise each row with ten spaces, and only 
replace five of them. So assuming you need the extra five spaces:

data = [record + [" "]*5 for record in curs]

provided curs returns lists, rather than tuples. (If not, it's 
easy to just convert using `list(record)`.

If you don't need the extra five columns, the code is even simpler:

data = list(curs)


What if you do want extra blank rows? Easiest to just add them at the 
end:

# initialise data as above, then add blanks
for i in range(how_many_extra_rows):
    data.append([" "]*10)

which can be simplified to:

data.extend([[" "]*10 for i in range(how_many_extra_rows)])



-- 
Steve

From nitinchandra1 at gmail.com  Tue May 10 01:29:37 2016
From: nitinchandra1 at gmail.com (nitin chandra)
Date: Tue, 10 May 2016 10:59:37 +0530
Subject: [Tutor] postgreSQL + psycopg2
In-Reply-To: <ngr56g$dl0$1@ger.gmane.org>
References: <CAFSKaezzv-DWfVgUJX0=6HbsH9iLYnC6KMJgrTV4FKR160V1MA@mail.gmail.com>
 <ngr56g$dl0$1@ger.gmane.org>
Message-ID: <CAFSKaewtOPHUgfZNt+FqW3=aHN9Tku9EZtb3mzmaHZwej4WAPA@mail.gmail.com>

Thanks Alan, Peter

but didn't work

    nextrow=(cursor1.execute(query, (design1,))).fetchone()
AttributeError: 'NoneType' object has no attribute 'fetchone'

1. Yes Alan, the variable 'design1' has a value '1'.

This is how I tested it from python command :

>>> import psycopg2
>>> import datetime
>>> line = (1, 'Vinayak', 'Salunke', '1', datetime.date(1982, 6, 6), 9871234567L, 'Tower-1,Millinium tower,Gurgaon,India', 0, 1, datetime.date(2016, 5, 6), datetime.datetime(2016, 5, 6, 22, 55, 5, tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=330, name=None)))
>>> design1 = line[3]
>>> print design1
1
>>> conn = psycopg2.connect(database="passtms", user="nitin", host="localhost", password="")
>>> cursor1 = conn.cursor()
>>> query=("""SELECT designation_name FROM designation WHERE designation_id = %s;""")
>>> nextrow = (query, (design1))
>>> nextrow
('SELECT designation_name FROM designation WHERE designation_id = %s;', '1')
>>> nextrow = cursor1.execute(query, (design1,))
>>> nextrow
>>>

When we run "cursor1.execute", that is when it gives us None.

How strange !!??

On 10 May 2016 at 04:36, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 09/05/16 22:14, nitin chandra wrote:
>
>> for line1 in smallLIST1:
>>     design1 = line1[3]
>>     print design1
>>     nextRow=cursor1.execute("SELECT designation_name FROM designation
>> WHERE designation_id = %s;", (design1))
>>     print nextRow
>>     print """<tr>"""
>>     for row in line1:
>>         print """<td>"""+str(row)+"""</td>"""
>>     print """</tr>"""
>>
>> 1st "print" shows values 1 , correctly.
>
> I assume you mean design1?
>
>> 2nd "print" shows "None".
>
> I don't know postgres API so i'll assume the %s is  the correct
> marker. In SQLite we'd use ?...
>
> Also to get the results row by row I'd expect to have
> to call fetchone() on the cursor:
>
> query = """
> SELECT designation_name
> FROM designation
> WHERE designation_id = %s;"""
>
> nextrow = cursor1.execute(query, (design1,)).fetchone()
>
> But Postgres DBAPI may be different...
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From __peter__ at web.de  Tue May 10 03:00:20 2016
From: __peter__ at web.de (Peter Otten)
Date: Tue, 10 May 2016 09:00:20 +0200
Subject: [Tutor] postgreSQL + psycopg2
References: <CAFSKaezzv-DWfVgUJX0=6HbsH9iLYnC6KMJgrTV4FKR160V1MA@mail.gmail.com>
 <ngr56g$dl0$1@ger.gmane.org>
 <CAFSKaewtOPHUgfZNt+FqW3=aHN9Tku9EZtb3mzmaHZwej4WAPA@mail.gmail.com>
Message-ID: <ngs0u5$po4$1@ger.gmane.org>

nitin chandra wrote:

> Thanks Alan, Peter
> 
> but didn't work
> 
>     nextrow=(cursor1.execute(query, (design1,))).fetchone()
> AttributeError: 'NoneType' object has no attribute 'fetchone'

Try without the method chaining:

cursor1.execute(query, (design1,))
nextrow = cursor1.fetchone()


From nitinchandra1 at gmail.com  Tue May 10 03:33:41 2016
From: nitinchandra1 at gmail.com (nitin chandra)
Date: Tue, 10 May 2016 13:03:41 +0530
Subject: [Tutor] postgreSQL + psycopg2
In-Reply-To: <ngs0u5$po4$1@ger.gmane.org>
References: <CAFSKaezzv-DWfVgUJX0=6HbsH9iLYnC6KMJgrTV4FKR160V1MA@mail.gmail.com>
 <ngr56g$dl0$1@ger.gmane.org>
 <CAFSKaewtOPHUgfZNt+FqW3=aHN9Tku9EZtb3mzmaHZwej4WAPA@mail.gmail.com>
 <ngs0u5$po4$1@ger.gmane.org>
Message-ID: <CAFSKaew1w2jdNVktGv_akZXzi-0EYfaa07rtns5cxyW-Q7jczA@mail.gmail.com>

IT WORKED !!!!

THANK YOU SSSOOOO MUCH ...phew .. Thank you

here is the result.

1
('Supervisor',)
<tr>
<td>1</td>
<td>Vinayak</td>
<td>Salunke</td>
<td>1</td>

Now I need to remove the braces and quotes .. :)

Thank you

Nitin

On 10 May 2016 at 12:30, Peter Otten <__peter__ at web.de> wrote:
> nitin chandra wrote:
>
>> Thanks Alan, Peter
>>
>> but didn't work
>>
>>     nextrow=(cursor1.execute(query, (design1,))).fetchone()
>> AttributeError: 'NoneType' object has no attribute 'fetchone'
>
> Try without the method chaining:
>
> cursor1.execute(query, (design1,))
> nextrow = cursor1.fetchone()
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From chris_roysmith at internode.on.net  Mon May  9 18:53:42 2016
From: chris_roysmith at internode.on.net (Chris Roy-Smith)
Date: Tue, 10 May 2016 08:53:42 +1000
Subject: [Tutor] is there a better way to do this?
In-Reply-To: <5730FB24.9020801@gybon.cz>
References: <573046AC.2000401@internode.on.net> <5730FB24.9020801@gybon.cz>
Message-ID: <573114F6.6080704@internode.on.net>

On 10/05/16 07:03, Ond?ej Rusek wrote:
> Dne 9.5.2016 v 10:13 Chris Roy-Smith napsal(a):
>> Hi
>> Python 3.4 Linux (ubuntu)
>>
>> This code does what I want.
>> curs is the result of a mysql query
>>
>>
>> data = [[" " for x in range(9)] for y in range(count)]
>> for (ddate, mood, walk, lag, sleep) in curs:
>>         data[row][0]=ddate
>>         data[row][1]=mood
>>         data[row][2]=walk
>>         data[row][3]=lag
>>         data[row][4]=sleep
>>         row +=1
>>
> if you want 'lists in list' (like your solution):
>
> data = []
> for ddate, mood, walk, lag, sleep in curs:
>     data += [ [ddate, mood, walk, lag, sleep] ]
>
> or 'tuples in list':
>
> data = []
> for ddate, mood, walk, lag, sleep in curs:
>   data += [ (ddate, mood, walk, lag, sleep) ]
>
> but for 'tuples in list'... simple:
>
> data = []
> for record in curs:
>   data += [record]
>
>
Thanks,
I hadn't considered having a second list of lists for my calculations,
Your solution is the sort of thing I was looking for.

From chris_roysmith at internode.on.net  Mon May  9 23:27:14 2016
From: chris_roysmith at internode.on.net (Chris Roy-Smith)
Date: Tue, 10 May 2016 13:27:14 +1000
Subject: [Tutor] is there a better way to do this?
In-Reply-To: <20160510020158.GZ12028@ando.pearwood.info>
References: <573046AC.2000401@internode.on.net>
 <20160510020158.GZ12028@ando.pearwood.info>
Message-ID: <57315512.4090100@internode.on.net>

On 10/05/16 12:01, Steven D'Aprano wrote:
> On Mon, May 09, 2016 at 06:13:32PM +1000, Chris Roy-Smith wrote:
>
>> data = [[" " for x in range(9)] for y in range(count)]
>> for (ddate, mood, walk, lag, sleep) in curs:
>>          data[row][0]=ddate
>>          data[row][1]=mood
>>          data[row][2]=walk
>>          data[row][3]=lag
>>          data[row][4]=sleep
>>          row +=1
>>
>> While I don't know a better way to do this, it seems a bit awkward, is
>> there a better way?
> Hmmm, it's hard to be sure because we don't really know what count is.
> Do you want a bunch of empty rows at the end? My guess is No.
>
> In your code above, you initialise each row with ten spaces, and only
> replace five of them. So assuming you need the extra five spaces:
>
> data = [record + [" "]*5 for record in curs]
>
> provided curs returns lists, rather than tuples. (If not, it's
> easy to just convert using `list(record)`.
>
> If you don't need the extra five columns, the code is even simpler:
>
> data = list(curs)
Thank you,
that's much better
I thought I needed the extra columns, but I changed things to use 2 
lists of lists
(one generated with the above line and another to hold my calculated 
results)

>
> What if you do want extra blank rows? Easiest to just add them at the
> end:
>
> # initialise data as above, then add blanks
> for i in range(how_many_extra_rows):
>      data.append([" "]*10)
>
> which can be simplified to:
>
> data.extend([[" "]*10 for i in range(how_many_extra_rows)])
>
>
>


From dkwolfe at gmail.com  Mon May  9 23:08:37 2016
From: dkwolfe at gmail.com (David Wolfe)
Date: Mon, 9 May 2016 23:08:37 -0400
Subject: [Tutor] Rate transition from 60hz to 1000hz
Message-ID: <CAG4wmDPsko7pdY9zhBj5KvErjSTo9M4bMb8152rrOTSuSb6NXA@mail.gmail.com>

Good Evening;

I'm collecting both video and force plate data, and I need to be able to
synchronize the two, so I can make some calculations.  The video data is at
60hz, and the force plate data is at 1000hz.  I don't want to truncate the
force plate data.

So, how do I perform a rate transition (or interpolation, or whatever) to
expand the data that is captured at 60hz to be able to synchronize it with
the data that has been captured at 1000hz?

Also, if I'm not using the correct terms, please let me know.  I'm new to
Python and programing, and I'm trying to learn as fast as i can.

Thanks,
David

From alan.gauld at yahoo.co.uk  Tue May 10 04:35:53 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 10 May 2016 09:35:53 +0100
Subject: [Tutor] Rate transition from 60hz to 1000hz
In-Reply-To: <CAG4wmDPsko7pdY9zhBj5KvErjSTo9M4bMb8152rrOTSuSb6NXA@mail.gmail.com>
References: <CAG4wmDPsko7pdY9zhBj5KvErjSTo9M4bMb8152rrOTSuSb6NXA@mail.gmail.com>
Message-ID: <ngs6h8$ia7$1@ger.gmane.org>

On 10/05/16 04:08, David Wolfe wrote:

> I'm collecting both video and force plate data, and I need to be able to
> synchronize the two, so I can make some calculations.  The video data is at
> 60hz, and the force plate data is at 1000hz.  I don't want to truncate the
> force plate data.

I have no idea what force plate data is but assuming it's nothing
special you have two sets of data, one at 1000Hz and one at 60Hz.
And you want to join them together at the appropriate points.

The problem is that 60 is not an exact factor of 1000 so you
will need to decide how you align the samples.

> So, how do I perform a rate transition (or interpolation, or whatever) to
> expand the data that is captured at 60hz to be able to synchronize it with
> the data that has been captured at 1000hz?

Interpolation over such a large sample range is tricky and risky.
The simplest way is to assume a straight line between samples.
So each interpolated value is just S2-S1/17 higher than the
previous value(S1).

A better way is to try to determine the current curve shape and apply
that. But it's much harder to do unless you know what kind of data to
expect!

> Also, if I'm not using the correct terms, please let me know.  I'm new to
> Python and programing, and I'm trying to learn as fast as i can.

This has nothing to do with Python or even programming per se.
Its really a math question. The same issues would apply if you
were tabulating the data by hand on paper.

That having been said, there may be some math libraries around
that you could use to do the sums for you. But it's not my area of
expertise so maybe some of the other tutor members will suggest
something in numpy or pandas or whatever.

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



From steve at pearwood.info  Tue May 10 08:15:30 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Tue, 10 May 2016 22:15:30 +1000
Subject: [Tutor] Rate transition from 60hz to 1000hz
In-Reply-To: <CAG4wmDPsko7pdY9zhBj5KvErjSTo9M4bMb8152rrOTSuSb6NXA@mail.gmail.com>
References: <CAG4wmDPsko7pdY9zhBj5KvErjSTo9M4bMb8152rrOTSuSb6NXA@mail.gmail.com>
Message-ID: <20160510121529.GB12028@ando.pearwood.info>

On Mon, May 09, 2016 at 11:08:37PM -0400, David Wolfe wrote:
> Good Evening;
> 
> I'm collecting both video and force plate data, and I need to be able to
> synchronize the two, so I can make some calculations.  The video data is at
> 60hz, and the force plate data is at 1000hz.  I don't want to truncate the
> force plate data.
> 
> So, how do I perform a rate transition (or interpolation, or whatever) to
> expand the data that is captured at 60hz to be able to synchronize it with
> the data that has been captured at 1000hz?

You need to explain in more detail what you actually have. What format 
is this data? What were you planning on doing with it? What sort of 
calculations were you intending to do? Are you using Numpy for the 
calculations?


-- 
Steve

From oscar.j.benjamin at gmail.com  Tue May 10 11:18:40 2016
From: oscar.j.benjamin at gmail.com (Oscar Benjamin)
Date: Tue, 10 May 2016 16:18:40 +0100
Subject: [Tutor] Rate transition from 60hz to 1000hz
In-Reply-To: <CAG4wmDPsko7pdY9zhBj5KvErjSTo9M4bMb8152rrOTSuSb6NXA@mail.gmail.com>
References: <CAG4wmDPsko7pdY9zhBj5KvErjSTo9M4bMb8152rrOTSuSb6NXA@mail.gmail.com>
Message-ID: <CAHVvXxQj=r54p4fGVoj9gWQzzk6AE_D6WtMeSMuhBBgoh_n9Nw@mail.gmail.com>

On 10 May 2016 at 04:08, David Wolfe <dkwolfe at gmail.com> wrote:
> Good Evening;
>
> I'm collecting both video and force plate data, and I need to be able to
> synchronize the two, so I can make some calculations.  The video data is at
> 60hz, and the force plate data is at 1000hz.  I don't want to truncate the
> force plate data.
>
> So, how do I perform a rate transition (or interpolation, or whatever) to
> expand the data that is captured at 60hz to be able to synchronize it with
> the data that has been captured at 1000hz?
>
> Also, if I'm not using the correct terms, please let me know.  I'm new to
> Python and programing, and I'm trying to learn as fast as i can.

The normal term for this is "resampling" and scipy has a function
called resample that does exactly this. Here's a demonstration:

>>> from scipy.signal import resample
>>> plate_signal = [1, 2, 1, 3, 1, 4, 2, 3, 4, 2]
>>> video_signal = [7, 8, 4]
>>> video_resampled = list(resample(video_signal, len(plate_signal)))
>>> video_resampled
[7.0000000000000009, 8.230109890796971, 8.735715605706849,
8.3236929465402536, 7.1514205649637077, 5.666666666666667,
4.4365567758696969, 3.9309510609598171, 4.3429737201264125,
5.5152461017029593]

This resamples the signal using interpolation. Notice that the last
samples of resample are increasing away from 4 (towards 7). This is
because resample uses a DFT-based method so it implicitly assumes that
the signal is periodic. This leads to a bit of distortion at the end
of your resampled signal - often that doesn't matter but it's worth
noticing.

You can read more about resample here:

http://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.signal.resample.html

I've added a list call because resample returns a numpy array. Do you
know what that is?

Presumably in your application video_signal is actually a 3D array
since at each frame you would have a 2D array of pixel values.
Resamples can handle this case too but exactly how to call it depends
on what sort of array you're using to store the video data.

I'm assuming here that you want to work offline. If you actually want
to do this computation online (as the data comes in) then you'd need
something different.

--
Oscar

From dyoo at hashcollision.org  Tue May 10 15:37:28 2016
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 10 May 2016 12:37:28 -0700
Subject: [Tutor] postgreSQL + psycopg2
In-Reply-To: <CAFSKaew1w2jdNVktGv_akZXzi-0EYfaa07rtns5cxyW-Q7jczA@mail.gmail.com>
References: <CAFSKaezzv-DWfVgUJX0=6HbsH9iLYnC6KMJgrTV4FKR160V1MA@mail.gmail.com>
 <ngr56g$dl0$1@ger.gmane.org>
 <CAFSKaewtOPHUgfZNt+FqW3=aHN9Tku9EZtb3mzmaHZwej4WAPA@mail.gmail.com>
 <ngs0u5$po4$1@ger.gmane.org>
 <CAFSKaew1w2jdNVktGv_akZXzi-0EYfaa07rtns5cxyW-Q7jczA@mail.gmail.com>
Message-ID: <CAGZAPF5zCemagWj8i+oxUpnTLy075jsEJoY_uothGSUwgb7_hg@mail.gmail.com>

> here is the result.
>
> 1
> ('Supervisor',)
> <tr>
> <td>1</td>
> <td>Vinayak</td>
> <td>Salunke</td>
> <td>1</td>
>
> Now I need to remove the braces and quotes .. :)


By the way, be very careful about generating HTML via naive string
concatenation.  If you can use a template engine such as Jinja
(http://jinja.pocoo.org/), please do so.


The main problem here is that the content you're using from the
database might have characters that look "html"-ish, in which case the
use of string concatenation is a vector for a Bobby-tables-like
injection attack.

    https://xkcd.com/327/

If you can't use a templating engine that knows about HTML escaping,
then you still need to add html escaping where the rows are being
constructed here:

    for row in line1:
        print """<td>"""+str(row)+"""</td>"""

See: https://docs.python.org/3/library/html.html#html.escape

Basically, any place where something "structured" (SQL queries, HTML)
is being constructed from something unstructured (string
concatenation), that's where injection attacks like to live.  Be
careful.


Hope this helps!

From alan.gauld at yahoo.co.uk  Tue May 10 18:27:27 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 10 May 2016 23:27:27 +0100
Subject: [Tutor] postgreSQL + psycopg2
In-Reply-To: <CAFSKaew1w2jdNVktGv_akZXzi-0EYfaa07rtns5cxyW-Q7jczA@mail.gmail.com>
References: <CAFSKaezzv-DWfVgUJX0=6HbsH9iLYnC6KMJgrTV4FKR160V1MA@mail.gmail.com>
 <ngr56g$dl0$1@ger.gmane.org>
 <CAFSKaewtOPHUgfZNt+FqW3=aHN9Tku9EZtb3mzmaHZwej4WAPA@mail.gmail.com>
 <ngs0u5$po4$1@ger.gmane.org>
 <CAFSKaew1w2jdNVktGv_akZXzi-0EYfaa07rtns5cxyW-Q7jczA@mail.gmail.com>
Message-ID: <ngtn8d$41u$1@ger.gmane.org>

On 10/05/16 08:33, nitin chandra wrote:

> here is the result.
> 
> 1
> ('Supervisor',)
> <tr>
> <td>1</td>
> <td>Vinayak</td>
> <td>Salunke</td>
> <td>1</td>
> 
> Now I need to remove the braces and quotes .. :)

No you don't. Those are just part of the string representation
that Python uses when printing a string inside a tuple.

If you print nextRow[0] instead of nextRow you
will get the bare string.

BTW Why are you using triple quotes? You only need them if
your string wraps over multiple lines. Single quotes (" or ')
will be fine for your purposes and are easier to type...

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



From nitinchandra1 at gmail.com  Wed May 11 01:37:17 2016
From: nitinchandra1 at gmail.com (nitin chandra)
Date: Wed, 11 May 2016 11:07:17 +0530
Subject: [Tutor] postgreSQL + psycopg2
In-Reply-To: <ngtn8d$41u$1@ger.gmane.org>
References: <CAFSKaezzv-DWfVgUJX0=6HbsH9iLYnC6KMJgrTV4FKR160V1MA@mail.gmail.com>
 <ngr56g$dl0$1@ger.gmane.org>
 <CAFSKaewtOPHUgfZNt+FqW3=aHN9Tku9EZtb3mzmaHZwej4WAPA@mail.gmail.com>
 <ngs0u5$po4$1@ger.gmane.org>
 <CAFSKaew1w2jdNVktGv_akZXzi-0EYfaa07rtns5cxyW-Q7jczA@mail.gmail.com>
 <ngtn8d$41u$1@ger.gmane.org>
Message-ID: <CAFSKaew3sgCoZBeO28ATv5_cfmAw6GOSdBPqn8RZLugUiRhoXQ@mail.gmail.com>

Thank you Danny, Alan,

@ Danny

I added 'str(formt(line1[0]))' .... will this do ?

@ Alan

I did just that .... nextRow[0]

Triple quotes ...... there is some part of code in multi-line ....
so... me being just lazyyy ... copy pasted / edited ... and left what
is working ..... just my excuse :P




On 11 May 2016 at 03:57, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 10/05/16 08:33, nitin chandra wrote:
>
>> here is the result.
>>
>> 1
>> ('Supervisor',)
>> <tr>
>> <td>1</td>
>> <td>Vinayak</td>
>> <td>Salunke</td>
>> <td>1</td>
>>
>> Now I need to remove the braces and quotes .. :)
>
> No you don't. Those are just part of the string representation
> that Python uses when printing a string inside a tuple.
>
> If you print nextRow[0] instead of nextRow you
> will get the bare string.
>
> BTW Why are you using triple quotes? You only need them if
> your string wraps over multiple lines. Single quotes (" or ')
> will be fine for your purposes and are easier to type...
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From dyoo at hashcollision.org  Wed May 11 02:17:27 2016
From: dyoo at hashcollision.org (Danny Yoo)
Date: Tue, 10 May 2016 23:17:27 -0700
Subject: [Tutor] postgreSQL + psycopg2
In-Reply-To: <CAFSKaew3sgCoZBeO28ATv5_cfmAw6GOSdBPqn8RZLugUiRhoXQ@mail.gmail.com>
References: <CAFSKaezzv-DWfVgUJX0=6HbsH9iLYnC6KMJgrTV4FKR160V1MA@mail.gmail.com>
 <ngr56g$dl0$1@ger.gmane.org>
 <CAFSKaewtOPHUgfZNt+FqW3=aHN9Tku9EZtb3mzmaHZwej4WAPA@mail.gmail.com>
 <ngs0u5$po4$1@ger.gmane.org>
 <CAFSKaew1w2jdNVktGv_akZXzi-0EYfaa07rtns5cxyW-Q7jczA@mail.gmail.com>
 <ngtn8d$41u$1@ger.gmane.org>
 <CAFSKaew3sgCoZBeO28ATv5_cfmAw6GOSdBPqn8RZLugUiRhoXQ@mail.gmail.com>
Message-ID: <CAGZAPF7RF83VRjms2aNHM+kk05irhNA3UoYVgQwUuKg2kS5Q-g@mail.gmail.com>

On Tue, May 10, 2016 at 10:37 PM, nitin chandra <nitinchandra1 at gmail.com> wrote:
> Thank you Danny, Alan,
>
> @ Danny
>
> I added 'str(formt(line1[0]))' .... will this do ?


Unfortunately, I don't know: what makes me hesitant is the following:

* The above is doing something just to line1[0], which looks odd.  Why
just line1[0]?

* What's the type of line1?  Is it a list of strings?  If so, then
calling str() on a string is redundant.

* I don't know what "formt" is.

So, yeah, I have enough questions and uncertainty that I need to
hedge.  This is not to say that you got it right or wrong, but rather
that I don't have enough information to decide either way.  There are
a lots of little details to get right when we program.  Rather than
handwave and assume that things are ok, I'll be truthful and admit my
ignorance.


Hope that makes sense!

From zemmoura.khalil at gmail.com  Wed May 11 09:00:47 2016
From: zemmoura.khalil at gmail.com (khalil zakaria Zemmoura)
Date: Wed, 11 May 2016 14:00:47 +0100
Subject: [Tutor] Behavior of dictionary in mapping keys that evaluate equal
Message-ID: <CAP4XKhUDxyevwSeO1N+Tg2viHKsUVEsE=oYFBbtrpC5YVXv3OA@mail.gmail.com>

Hi,

Suppose we have a dict
Dic = { True: 'yes', 1: 'No'}

According to the Python 3 documentation, the keys must have a unique value
so True is converted to integer because of the type coercion (boolean are
subtype of integer) so boolean are winded to integer to be compared.

Am I missing something?

If that's what happen, why when running Dic.items() it return [(True,
'No')] instead of [(1, 'No')]

From cs at zip.com.au  Wed May 11 18:42:45 2016
From: cs at zip.com.au (cs at zip.com.au)
Date: Thu, 12 May 2016 08:42:45 +1000
Subject: [Tutor] Behavior of dictionary in mapping keys that evaluate
 equal
In-Reply-To: <CAP4XKhUDxyevwSeO1N+Tg2viHKsUVEsE=oYFBbtrpC5YVXv3OA@mail.gmail.com>
References: <CAP4XKhUDxyevwSeO1N+Tg2viHKsUVEsE=oYFBbtrpC5YVXv3OA@mail.gmail.com>
Message-ID: <20160511224245.GA22481@cskk.homeip.net>

On 11May2016 14:00, khalil zakaria Zemmoura <zemmoura.khalil at gmail.com> wrote:
>Suppose we have a dict
>Dic = { True: 'yes', 1: 'No'}
>
>According to the Python 3 documentation, the keys must have a unique value
>so True is converted to integer because of the type coercion (boolean are
>subtype of integer) so boolean are winded to integer to be compared.

As it happens. The core lesson here is that usually you want all your 
dictionary keys to be the same type.

>If that's what happen, why when running Dic.items() it return [(True,
>'No')] instead of [(1, 'No')]

Because the dictionary is assembled sequentially (probably an implementation 
detail, though since Python expressions are evaluated left to right it might 
possibly be guarrenteed).

So:

  First 'yes' is loaded into the dict with the key True.

  The 'No' is loaded, using key 1. This finds the same slot as True, and puts 
  'No' there. Without changing the key value. So true now has 'No' stored with 
  it.

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

From steve at pearwood.info  Wed May 11 21:19:21 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Thu, 12 May 2016 11:19:21 +1000
Subject: [Tutor] Behavior of dictionary in mapping keys that evaluate
 equal
In-Reply-To: <CAP4XKhUDxyevwSeO1N+Tg2viHKsUVEsE=oYFBbtrpC5YVXv3OA@mail.gmail.com>
References: <CAP4XKhUDxyevwSeO1N+Tg2viHKsUVEsE=oYFBbtrpC5YVXv3OA@mail.gmail.com>
Message-ID: <20160512011921.GE12028@ando.pearwood.info>

On Wed, May 11, 2016 at 02:00:47PM +0100, khalil zakaria Zemmoura wrote:
> Hi,
> 
> Suppose we have a dict
> Dic = { True: 'yes', 1: 'No'}
> 
> According to the Python 3 documentation, the keys must have a unique value
> so True is converted to integer because of the type coercion (boolean are
> subtype of integer) so boolean are winded to integer to be compared.

No, not quite. Keys aren't converted to anything. The above is 
equivalent to:

Dic = {}
Dic[True] = 'yes'
Dic[1] = 'no'

That part is straight-forward. But remember that True == 1:

py> True == 1
True

and they have the same hash:

py> hash(True), hash(1)
(1, 1)

so as far as Python is concerned, they are the same key. The same 
applies to the float 1.0:

py> d = {True: 'yes'}
py> d[1]
'yes'
py> d[1.0]
'yes'


One last fact to remember: if the key is already found in the dict, it 
isn't replaced. So:

py> d = {1: 'no'}
py> d[True] = 'yes'
py> d
{1: 'yes'}


Does this now explain why

{True: 'yes', 1: 'no'}

returns {True: 'no'}?


-- 
Steve

From __peter__ at web.de  Thu May 12 02:46:40 2016
From: __peter__ at web.de (Peter Otten)
Date: Thu, 12 May 2016 08:46:40 +0200
Subject: [Tutor] Behavior of dictionary in mapping keys that evaluate
 equal
References: <CAP4XKhUDxyevwSeO1N+Tg2viHKsUVEsE=oYFBbtrpC5YVXv3OA@mail.gmail.com>
 <20160512011921.GE12028@ando.pearwood.info>
Message-ID: <nh18si$6dk$1@ger.gmane.org>

Steven D'Aprano wrote:

> On Wed, May 11, 2016 at 02:00:47PM +0100, khalil zakaria Zemmoura wrote:
>> Hi,
>> 
>> Suppose we have a dict
>> Dic = { True: 'yes', 1: 'No'}
>> 
>> According to the Python 3 documentation, the keys must have a unique
>> value so True is converted to integer because of the type coercion
>> (boolean are subtype of integer) so boolean are winded to integer to be
>> compared.
> 
> No, not quite. Keys aren't converted to anything. The above is
> equivalent to:
> 
> Dic = {}
> Dic[True] = 'yes'
> Dic[1] = 'no'
> 
> That part is straight-forward. But remember that True == 1:
> 
> py> True == 1
> True
> 
> and they have the same hash:
> 
> py> hash(True), hash(1)
> (1, 1)
> 
> so as far as Python is concerned, they are the same key. The same
> applies to the float 1.0:
> 
> py> d = {True: 'yes'}
> py> d[1]
> 'yes'
> py> d[1.0]
> 'yes'
> 
> 
> One last fact to remember: if the key is already found in the dict, it
> isn't replaced. So:
> 
> py> d = {1: 'no'}
> py> d[True] = 'yes'
> py> d
> {1: 'yes'}
> 
> 
> Does this now explain why
> 
> {True: 'yes', 1: 'no'}
> 
> returns {True: 'no'}?

As Steven says, there is no conversion. The mechanism is completely general: 
The first of a sequence of equal keys wins. 

Here is an example with a custom class:

>>> class Key:
...     def __eq__(self, other):
...         return other == 1
...     def __hash__(self):
...         return 1
...     def __repr__(self):
...         return "<my custom key>"
... 
>>> int(Key())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string, a bytes-like object or a number, 
not 'Key'

Even though there is no way to convert a Key to int the dict literals behave 
as with bool and int:

>>> d = {1: "a", Key(): "b"}
>>> d
{1: 'b'}
>>> d = {Key(): "a", 1: "b"}
>>> d
{<my custom key>: 'b'}




From zemmoura.khalil at gmail.com  Thu May 12 12:41:34 2016
From: zemmoura.khalil at gmail.com (khalil zakaria Zemmoura)
Date: Thu, 12 May 2016 17:41:34 +0100
Subject: [Tutor] Behavior of dictionary in mapping keys that evaluate
 equal
In-Reply-To: <nh18si$6dk$1@ger.gmane.org>
References: <CAP4XKhUDxyevwSeO1N+Tg2viHKsUVEsE=oYFBbtrpC5YVXv3OA@mail.gmail.com>
 <20160512011921.GE12028@ando.pearwood.info>
 <nh18si$6dk$1@ger.gmane.org>
Message-ID: <CAP4XKhXgUJuQ95d-f2oymtTpKHZhhdMQZzfyV2e9jc5N9ecCkA@mail.gmail.com>

Steven D'Aprano wrote:

> On Wed, May 11, 2016 at 02:00:47PM +0100, khalil zakaria Zemmoura wrote:
>> Hi,
>>
>> Suppose we have a dict
>> Dic = { True: 'yes', 1: 'No'}
>>
>> According to the Python 3 documentation, the keys must have a unique
>> value so True is converted to integer because of the type coercion
>> (boolean are subtype of integer) so boolean are winded to integer to be
>> compared.
>
> No, not quite. Keys aren't converted to anything. The above is
> equivalent to:
>
> Dic = {}
> Dic[True] = 'yes'
> Dic[1] = 'no'
>
> That part is straight-forward. But remember that True == 1:
>
> py> True == 1
> True
>
> and they have the same hash:
>
> py> hash(True), hash(1)
> (1, 1)
>
> so as far as Python is concerned, they are the same key. The same
> applies to the float 1.0:
>
> py> d = {True: 'yes'}
> py> d[1]
> 'yes'
> py> d[1.0]
> 'yes'
>
>
> One last fact to remember: if the key is already found in the dict, it
> isn't replaced. So:
>
> py> d = {1: 'no'}
> py> d[True] = 'yes'
> py> d
> {1: 'yes'}
>
>
> Does this now explain why
>
> {True: 'yes', 1: 'no'}
>
> returns {True: 'no'}?

As Steven says, there is no conversion. The mechanism is completely general:
The first of a sequence of equal keys wins.

Here is an example with a custom class:

>>> class Key:
...     def __eq__(self, other):
...         return other == 1
...     def __hash__(self):
...         return 1
...     def __repr__(self):
...         return "<my custom key>"
...
>>> int(Key())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string, a bytes-like object or a number,
not 'Key'

Even though there is no way to convert a Key to int the dict literals behave
as with bool and int:

>>> d = {1: "a", Key(): "b"}
>>> d
{1: 'b'}
>>> d = {Key(): "a", 1: "b"}
>>> d
{<my custom key>: 'b'}

Thanks a lot, what I was missing is the behavior of dict constructor, so
that's gives me more understanding.

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

From neilc at norwich.edu  Fri May 13 16:25:49 2016
From: neilc at norwich.edu (Neil D. Cerutti)
Date: Fri, 13 May 2016 16:25:49 -0400
Subject: [Tutor] sqlite
In-Reply-To: <ngagp1$8a3$1@ger.gmane.org>
References: <CAC7HCj9+EC4s3ityBhNe62LpAk6YfJs_sAahj8xLt9bbgMrBbg@mail.gmail.com>
 <ngagp1$8a3$1@ger.gmane.org>
Message-ID: <nh5d8e$4rj$1@ger.gmane.org>

On 5/3/2016 11:40 AM, Alan Gauld via Tutor wrote:
> On 03/05/16 10:09, Crusier wrote:
>
>> I am just wondering if there is any good reference which I can learn how to
>> program SQLITE using Python
>>
>> I can not find any book is correlated to Sqlite using Python.
>
> You can try my tutorial below.
>
> http://www.alan-g.me.uk/tutor/tutdbms.htm
>
> If you want very similar information in book form then
> our book 'Python Projects' contains a chapter on databases,
> half of which is SQLite based.
>
> If you want a good book on SQLite itself I can recommend:
>
> Using SQLIte by Kreibich.

 From your tutorial:

query = '''INSERT INTO Address
                (First,Last,House,Street,District,Town,PostCode,Phone)
                Values ("%s","%s","%s","%s","%s","%s","%s","%s")''' %\
                (first, last, house, street, district, town, code, phone)

I am not an expert on SQLite, but that doesn't appear to be a wise way 
to call SQL from Python. Are the double-quotes enough to protect you 
from malicious data?

-- 
Neil Cerutti


From alan.gauld at yahoo.co.uk  Fri May 13 20:36:35 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 14 May 2016 01:36:35 +0100
Subject: [Tutor] sqlite
In-Reply-To: <nh5d8e$4rj$1@ger.gmane.org>
References: <CAC7HCj9+EC4s3ityBhNe62LpAk6YfJs_sAahj8xLt9bbgMrBbg@mail.gmail.com>
 <ngagp1$8a3$1@ger.gmane.org> <nh5d8e$4rj$1@ger.gmane.org>
Message-ID: <nh5rui$nd0$1@ger.gmane.org>

On 13/05/16 21:25, Neil D. Cerutti wrote:

>  From your tutorial:
> 
> query = '''INSERT INTO Address
>                 (First,Last,House,Street,District,Town,PostCode,Phone)
>                 Values ("%s","%s","%s","%s","%s","%s","%s","%s")''' %\
>                 (first, last, house, street, district, town, code, phone)
> 
> I am not an expert on SQLite, but that doesn't appear to be a wise way 
> to call SQL from Python. Are the double-quotes enough to protect you 
> from malicious data?

No, and if you carry on reading you will find:

------------------
A Word about Security

While the code above works and demonstrates how to call SQL from Python
it does have one significant flaw. Because I used string formatting to
construct the queries it is possible for a malicious user to enter some
rogue SQL code as input. This rogue code then gets inserted into the
query using the format string and is executed, potentially deleting
vital data. To avoid that, the execute() API call has an extra trick up
its sleeve....

-------------



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



From __peter__ at web.de  Sat May 14 03:21:28 2016
From: __peter__ at web.de (Peter Otten)
Date: Sat, 14 May 2016 09:21:28 +0200
Subject: [Tutor] sqlite
References: <CAC7HCj9+EC4s3ityBhNe62LpAk6YfJs_sAahj8xLt9bbgMrBbg@mail.gmail.com>
 <ngagp1$8a3$1@ger.gmane.org> <nh5d8e$4rj$1@ger.gmane.org>
 <nh5rui$nd0$1@ger.gmane.org>
Message-ID: <nh6jls$eci$1@ger.gmane.org>

Alan Gauld via Tutor wrote:

> On 13/05/16 21:25, Neil D. Cerutti wrote:
> 
>>  From your tutorial:
>> 
>> query = '''INSERT INTO Address
>>                 (First,Last,House,Street,District,Town,PostCode,Phone)
>>                 Values ("%s","%s","%s","%s","%s","%s","%s","%s")''' %\
>>                 (first, last, house, street, district, town, code, phone)
>> 
>> I am not an expert on SQLite, but that doesn't appear to be a wise way
>> to call SQL from Python. Are the double-quotes enough to protect you
>> from malicious data?
> 
> No, and if you carry on reading you will find:
> 
> ------------------
> A Word about Security
> 
> While the code above works and demonstrates how to call SQL from Python
> it does have one significant flaw. Because I used string formatting to
> construct the queries it is possible for a malicious user to enter some
> rogue SQL code as input. This rogue code then gets inserted into the
> query using the format string and is executed, potentially deleting
> vital data. To avoid that, the execute() API call has an extra trick up
> its sleeve....
> 
> -------------

I have to say it: giving a newbie a bad idea plus broken example code -- and 
then follow up with a warning will hardly ever work out the way you'd hope.


From RosenB16 at student.riverdell.org  Sun May 15 17:45:33 2016
From: RosenB16 at student.riverdell.org (Rosen, Brian - 2016)
Date: Sun, 15 May 2016 21:45:33 +0000
Subject: [Tutor] Curses Module
Message-ID: <BLUPR04MB291068591F0142BF1F4127192760@BLUPR04MB291.namprd04.prod.outlook.com>

To Whom it May Concern,


  I am a high school student currently enrolled in an Intro to Computer Programming Class. In my current assignment, I would like to import the curses module into either Python 2.7 or Python 3.4. However, whenever I attempt to import it, there is an Import Error that states "No module named '_curses'.


Would you have any idea as to how to make the curses module available for use in my programming? Thank you.


Sincerely,

Brian Rosen

From joel.goldstick at gmail.com  Mon May 16 10:02:21 2016
From: joel.goldstick at gmail.com (Joel Goldstick)
Date: Mon, 16 May 2016 10:02:21 -0400
Subject: [Tutor] Curses Module
In-Reply-To: <BLUPR04MB291068591F0142BF1F4127192760@BLUPR04MB291.namprd04.prod.outlook.com>
References: <BLUPR04MB291068591F0142BF1F4127192760@BLUPR04MB291.namprd04.prod.outlook.com>
Message-ID: <CAPM-O+zYt3v4t-ip8a8e6Fo4+EPFnciJBe4VWe_fA+cV_9vcVQ@mail.gmail.com>

On Sun, May 15, 2016 at 5:45 PM, Rosen, Brian - 2016
<RosenB16 at student.riverdell.org> wrote:
> To Whom it May Concern,
>
>
>   I am a high school student currently enrolled in an Intro to Computer Programming Class. In my current assignment, I would like to import the curses module into either Python 2.7 or Python 3.4. However, whenever I attempt to import it, there is an Import Error that states "No module named '_curses'.
>
>
> Would you have any idea as to how to make the curses module available for use in my programming? Thank you.
>
>
> Sincerely,
>
> Brian Rosen
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

Which operating system are you using?

-- 
Joel Goldstick
http://joelgoldstick.com/blog
http://cc-baseballstats.info/stats/birthdays

From mail at timgolden.me.uk  Mon May 16 10:06:47 2016
From: mail at timgolden.me.uk (Tim Golden)
Date: Mon, 16 May 2016 15:06:47 +0100
Subject: [Tutor] Curses Module
In-Reply-To: <BLUPR04MB291068591F0142BF1F4127192760@BLUPR04MB291.namprd04.prod.outlook.com>
References: <BLUPR04MB291068591F0142BF1F4127192760@BLUPR04MB291.namprd04.prod.outlook.com>
Message-ID: <5739D3F7.8070309@timgolden.me.uk>

On 15/05/2016 22:45, Rosen, Brian - 2016 wrote:
> To Whom it May Concern,
> 
> 
> I am a high school student currently enrolled in an Intro to Computer
> Programming Class. In my current assignment, I would like to import
> the curses module into either Python 2.7 or Python 3.4. However,
> whenever I attempt to import it, there is an Import Error that states
> "No module named '_curses'.

Assuming you're  on Windows, you'll need to download a 3rd party curses
module, such as:

http://www.lfd.uci.edu/~gohlke/pythonlibs/#curses

and install it via pip.

TJG

From alan.gauld at yahoo.co.uk  Mon May 16 12:46:51 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 16 May 2016 17:46:51 +0100
Subject: [Tutor] Curses Module
In-Reply-To: <BLUPR04MB291068591F0142BF1F4127192760@BLUPR04MB291.namprd04.prod.outlook.com>
References: <BLUPR04MB291068591F0142BF1F4127192760@BLUPR04MB291.namprd04.prod.outlook.com>
Message-ID: <nhcthp$20l$1@ger.gmane.org>

On 15/05/16 22:45, Rosen, Brian - 2016 wrote:

>...In my current assignment, I would like to import the curses module
> into either Python 2.7 or Python 3.4. However,
> whenever I attempt to import it, there is an Import Error

Curses is only available in the standard library on Unix-like
operating systems: Solaris, Linux, MacOS etc.

If you use Windows you can get third party versions although I've had
very mixed results using them. I usually prefer to install Cygwin and
use the Python/curses combination for that.

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



From ckava3 at gmail.com  Tue May 17 04:28:12 2016
From: ckava3 at gmail.com (Chris Kavanagh)
Date: Tue, 17 May 2016 04:28:12 -0400
Subject: [Tutor] Adding to a dict through a for loop confusion.
Message-ID: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>

Could someone tell me why this different behavior occurs between these 2
code snippets, please. The 1st example has quotes around it ['item'] only
adds the last item to the dict (cart). In the 2nd example the item does not
have quotes around it [item] and every entry is added to the dict.

Why?


# Example #1
cart_items = ['1','2','3','4','5']

cart = {}

for item in cart_items:
    cart['item'] = item

print cart

#output
{'item': 5}

------------------------------------------------------------------------------------------------------------------------------------------------
# Example #2
cart_items = ['1','2','3','4','5']

cart = {}

for item in cart_items:
    cart[item] = item

print cart

# output
{'1': '1', '3': '3', '2': '2', '5': '5', '4': '4'}


Thanks you for the help.

From nulla.epistola at web.de  Tue May 17 05:00:56 2016
From: nulla.epistola at web.de (Sibylle Koczian)
Date: Tue, 17 May 2016 11:00:56 +0200
Subject: [Tutor] Adding to a dict through a for loop confusion.
In-Reply-To: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>
References: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>
Message-ID: <61974bc9-7616-8c4b-57cf-9d63be1755d6@web.de>

Hello,

Am 17.05.2016 um 10:28 schrieb Chris Kavanagh:
> Could someone tell me why this different behavior occurs between these 2
> code snippets, please. The 1st example has quotes around it ['item'] only
> adds the last item to the dict (cart). In the 2nd example the item does not
> have quotes around it [item] and every entry is added to the dict.
>
> Why?
>
>
> # Example #1
> cart_items = ['1','2','3','4','5']
>
> cart = {}
>
> for item in cart_items:
>     cart['item'] = item
>
> print cart
>
> #output
> {'item': 5}
>

Here you assign every item from your list to a dictionary entry with the 
same key 'item' - that's a string literal that hasn't got anything to do 
with the name item you give to each list element in turn.

Because a dictionary can only contain one entry for each key the value 
of that entry cart['item'] is overwritten in every step through the 
loop. Only the result of the last step is kept.

> ------------------------------------------------------------------------------------------------------------------------------------------------
> # Example #2
> cart_items = ['1','2','3','4','5']
>
> cart = {}
>
> for item in cart_items:
>     cart[item] = item
>
> print cart
>
> # output
> {'1': '1', '3': '3', '2': '2', '5': '5', '4': '4'}
>

Here you take the value from the list cart_items, called item, for the 
key and for the value of the dictionary entry. So every entry gets a 
different key and your dictionary has as many entries as the list has 
elements.

But did you really want to get a dictionary with the same values for key 
and value?

HTH
Sibylle



From alan.gauld at yahoo.co.uk  Tue May 17 05:04:25 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 17 May 2016 10:04:25 +0100
Subject: [Tutor] Adding to a dict through a for loop confusion.
In-Reply-To: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>
References: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>
Message-ID: <nhemqo$l5r$1@ger.gmane.org>

On 17/05/16 09:28, Chris Kavanagh wrote:

> # Example #1
> cart_items = ['1','2','3','4','5']
> 
> cart = {}
> 
> for item in cart_items:
>     cart['item'] = item

'item' is a literal string. It never changes.
So you keep overwriting the dict entry so that
at the end of the loop the dict contains the
last value associated with your literal key 'item'

> #output
> {'item': 5}
> 
> ------------------------------------------------------------------------------------------------------------------------------------------------
> # Example #2
> cart_items = ['1','2','3','4','5']
> 
> cart = {}
> 
> for item in cart_items:
>     cart[item] = item

here you use the actual item from your data as both
the key and the value. So you wind up with a dict
containing a key/value pair for each value in your
data list.

> # output
> {'1': '1', '3': '3', '2': '2', '5': '5', '4': '4'}

That's not a very common requirement though, usually
you would have different values from the keys.

Maybe something like:

for item in cart_items:
    cart[item] = int(item)

which stores an integer value against the string
representation:

{'1': 1, '3': 3, '2': 2, '5': 5, '4': 4}

Notice also that dicts don't usually print out
in the same order as you created them. In fact
the 'order' can even change over the life of your
program, as you add/remove elements.

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



From nulla.epistola at web.de  Tue May 17 05:00:56 2016
From: nulla.epistola at web.de (Sibylle Koczian)
Date: Tue, 17 May 2016 11:00:56 +0200
Subject: [Tutor] Adding to a dict through a for loop confusion.
In-Reply-To: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>
References: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>
Message-ID: <61974bc9-7616-8c4b-57cf-9d63be1755d6@web.de>

Hello,

Am 17.05.2016 um 10:28 schrieb Chris Kavanagh:
> Could someone tell me why this different behavior occurs between these 2
> code snippets, please. The 1st example has quotes around it ['item'] only
> adds the last item to the dict (cart). In the 2nd example the item does not
> have quotes around it [item] and every entry is added to the dict.
>
> Why?
>
>
> # Example #1
> cart_items = ['1','2','3','4','5']
>
> cart = {}
>
> for item in cart_items:
>     cart['item'] = item
>
> print cart
>
> #output
> {'item': 5}
>

Here you assign every item from your list to a dictionary entry with the 
same key 'item' - that's a string literal that hasn't got anything to do 
with the name item you give to each list element in turn.

Because a dictionary can only contain one entry for each key the value 
of that entry cart['item'] is overwritten in every step through the 
loop. Only the result of the last step is kept.

> ------------------------------------------------------------------------------------------------------------------------------------------------
> # Example #2
> cart_items = ['1','2','3','4','5']
>
> cart = {}
>
> for item in cart_items:
>     cart[item] = item
>
> print cart
>
> # output
> {'1': '1', '3': '3', '2': '2', '5': '5', '4': '4'}
>

Here you take the value from the list cart_items, called item, for the 
key and for the value of the dictionary entry. So every entry gets a 
different key and your dictionary has as many entries as the list has 
elements.

But did you really want to get a dictionary with the same values for key 
and value?

HTH
Sibylle


From cs at zip.com.au  Tue May 17 05:01:48 2016
From: cs at zip.com.au (cs at zip.com.au)
Date: Tue, 17 May 2016 19:01:48 +1000
Subject: [Tutor] Adding to a dict through a for loop confusion.
In-Reply-To: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>
References: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>
Message-ID: <20160517090148.GA41951@cskk.homeip.net>

On 17May2016 04:28, Chris Kavanagh <ckava3 at gmail.com> wrote:
>Could someone tell me why this different behavior occurs between these 2
>code snippets, please. The 1st example has quotes around it ['item'] only
>adds the last item to the dict (cart). In the 2nd example the item does not
>have quotes around it [item] and every entry is added to the dict.
>
>Why?
[...]
># Example #1
>cart_items = ['1','2','3','4','5']
>cart = {}
>for item in cart_items:
>    cart['item'] = item

This for loop assigns the values '1','2','3','4','5' in succession to the 
variable named "item". Then the body of the loop assigns that value (via the 
variable "item") to the single dictionary slot with the fixed key with string 
value 'item' i.e. always the same slot.  And the last item is the one kept.  
All the earlier assignments are overwritten by the later ones: they happen, but 
are replaced.

>print cart
>#output
>{'item': 5}

Which you see above.

># Example #2
>cart_items = ['1','2','3','4','5']
>cart = {}
>for item in cart_items:
>    cart[item] = item

Here, the variable named "item" takes on the values as before, but the diction 
slot chosen also comes form that variable. So each value ends up in its own 
slot as your output shows.

>print cart
># output
>{'1': '1', '3': '3', '2': '2', '5': '5', '4': '4'}

The essential difference here is that in the first example the expression for 
the slot in the dictionary is the expression:

  'item'

which is simply the fixed string 'item'. In the second example the expression 
is:

  item

which produces the current value stored in the variable "item".

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

From ckava3 at gmail.com  Tue May 17 18:56:40 2016
From: ckava3 at gmail.com (Chris Kavanagh)
Date: Tue, 17 May 2016 18:56:40 -0400
Subject: [Tutor] Adding to a dict through a for loop confusion.
In-Reply-To: <20160517090148.GA41951@cskk.homeip.net>
References: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>
 <20160517090148.GA41951@cskk.homeip.net>
Message-ID: <CAOywziAsrVXg8s38-=OEyAFu53wduECMQR3wzD1rQZmkRC5B5g@mail.gmail.com>

Thank you so much for the help, and the example!

So, by putting quotes around a dict key, like so dict["key"] or in my case
cart["item"] this makes the dict have ONE key. The loop assigns the
cart_items to this ONE key until the end of the loop, and I'm left with
{'item': 5}. . .

Where as if you do NOT put the key in quotes, dict[key] or cart[item], this
basically means the dict has as many keys as you're iterating through. In
other words it assigns the cart_item as a key and a value, and saves them
all to the dict.

Is that correct?

On Tue, May 17, 2016 at 5:01 AM, <cs at zip.com.au> wrote:

> On 17May2016 04:28, Chris Kavanagh <ckava3 at gmail.com> wrote:
>
>> Could someone tell me why this different behavior occurs between these 2
>> code snippets, please. The 1st example has quotes around it ['item'] only
>> adds the last item to the dict (cart). In the 2nd example the item does
>> not
>> have quotes around it [item] and every entry is added to the dict.
>>
>> Why?
>>
> [...]
>
>> # Example #1
>> cart_items = ['1','2','3','4','5']
>> cart = {}
>> for item in cart_items:
>>    cart['item'] = item
>>
>
> This for loop assigns the values '1','2','3','4','5' in succession to the
> variable named "item". Then the body of the loop assigns that value (via
> the variable "item") to the single dictionary slot with the fixed key with
> string value 'item' i.e. always the same slot.  And the last item is the
> one kept.  All the earlier assignments are overwritten by the later ones:
> they happen, but are replaced.
>
> print cart
>> #output
>> {'item': 5}
>>
>
> Which you see above.
>
> # Example #2
>> cart_items = ['1','2','3','4','5']
>> cart = {}
>> for item in cart_items:
>>    cart[item] = item
>>
>
> Here, the variable named "item" takes on the values as before, but the
> diction slot chosen also comes form that variable. So each value ends up in
> its own slot as your output shows.
>
> print cart
>> # output
>> {'1': '1', '3': '3', '2': '2', '5': '5', '4': '4'}
>>
>
> The essential difference here is that in the first example the expression
> for the slot in the dictionary is the expression:
>
>  'item'
>
> which is simply the fixed string 'item'. In the second example the
> expression is:
>
>  item
>
> which produces the current value stored in the variable "item".
>
> Cheers,
> Cameron Simpson <cs at zip.com.au>
>

From alan.gauld at yahoo.co.uk  Tue May 17 19:10:16 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 18 May 2016 00:10:16 +0100
Subject: [Tutor] Adding to a dict through a for loop confusion.
In-Reply-To: <CAOywziAsrVXg8s38-=OEyAFu53wduECMQR3wzD1rQZmkRC5B5g@mail.gmail.com>
References: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>
 <20160517090148.GA41951@cskk.homeip.net>
 <CAOywziAsrVXg8s38-=OEyAFu53wduECMQR3wzD1rQZmkRC5B5g@mail.gmail.com>
Message-ID: <nhg8cm$6oq$1@ger.gmane.org>

On 17/05/16 23:56, Chris Kavanagh wrote:

> So, by putting quotes around a dict key, like so dict["key"] or in my case
> cart["item"] this makes the dict have ONE key. The loop assigns the
> cart_items to this ONE key until the end of the loop, and I'm left with
> {'item': 5}. . .
> 
> Where as if you do NOT put the key in quotes, dict[key] or cart[item], this
> basically means the dict has as many keys as you're iterating through. In
> other words it assigns the cart_item as a key and a value, and saves them
> all to the dict.
> 
> Is that correct?

Sort of, but not for the reasons you give.
Putting the key in quotes makes it a literal string.
That is, a fixed value, just like 2 or 5.5 or True.
These are literal integer, float and boolean values
respectively.

So you could just as well have done:

for item in cart_items:
    cart[2] = item

And everything would be stored under a key of 2.

Or

for item in cart_items:
    cart[True] = item

And everything would get stored on a key of True.

The quotes turn the sequence of characters 'i','t','e','m'
into the string value 'item'. The fact that the string is
the same as the variable name in your for loop is completely
coincidental. Python doesn't recognise them as in any way
related.

So in the first case the issue is that you stored your
values in a single unchanging key.

Whereas in the second loop you stored your values against
a key which was a variable that changed in each iteration.

The fact you used quotes is only significant in that quotes
are what you use to create a literal string value. But it
was the fact that it was a fixed value that made everything
appear in the same place (and hence be overwritten), not the
quotes per se.


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



From steve at pearwood.info  Tue May 17 21:54:09 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 18 May 2016 11:54:09 +1000
Subject: [Tutor] Adding to a dict through a for loop confusion.
In-Reply-To: <CAOywziAsrVXg8s38-=OEyAFu53wduECMQR3wzD1rQZmkRC5B5g@mail.gmail.com>
References: <CAOywziAMj0kmbVL61upaBhxMNxcFQB8xdAwXMQJJLBcbvvc_sw@mail.gmail.com>
 <20160517090148.GA41951@cskk.homeip.net>
 <CAOywziAsrVXg8s38-=OEyAFu53wduECMQR3wzD1rQZmkRC5B5g@mail.gmail.com>
Message-ID: <20160518015407.GL12028@ando.pearwood.info>

On Tue, May 17, 2016 at 06:56:40PM -0400, Chris Kavanagh wrote:
> Thank you so much for the help, and the example!
> 
> So, by putting quotes around a dict key, like so dict["key"] or in my case
> cart["item"] this makes the dict have ONE key. The loop assigns the
> cart_items to this ONE key until the end of the loop, and I'm left with
> {'item': 5}. . .

Chris, you're still thinking about this the wrong way. Let's look at a 
slightly different example which hopefully will give you some better 
perspective. I'm going to use a list, not a dict.


I hope it is obvious what is going on here:

py> mylist = [100, 200, 300]
py> for i in (0, 1, 2):
...     mylist[i] = 1000 + i
...
py> mylist
[1000, 1001, 1002]

If we "unroll" the for-loop and turn it into individual lines of code, 
we're effectively executing this:

    i = 0
    mylist[i] = 1000 + i  # here, i==0 so mylist[0] = 1000
    i = 1
    mylist[i] = 1000 + i  # here, i==1 so mylist[1] = 1001
    i = 2
    mylist[i] = 1000 + i  # here, i==2 so mylist[2] = 1002


Any questions?

Now, let's look at this one instead:

py> mylist = [100, 200, 300]
py> for i in (0, 1, 2):
...     mylist[0] = 1000 + i
...
py> mylist
[1004, 200, 300]

Let's unroll the for-loop:

    i = 0
    mylist[0] = 1000 + i
    i = 1
    mylist[0] = 1000 + i
    i = 2
    mylist[0] = 1000 + i


So far, all of this should hopefully be obvious. If you keep assigning 
to mylist[0] each time, only the first item of the list will be changed. 
In the first case, you assigned to a different item each time through 
the loop, because you wrote mylist[i] and i changed each time. In the 
second case, you assigned to mylist[0] each time.

There's nothing fancy or tricky going on here. The difference is 100% 
and entirely because of the difference between writing the VARIABLE i 
and writing the CONSTANT 0.

And it is the same with dict keys. If you loop over the dict:

cart_items = ['one', 'two', 'three']
for item in cart_items:
    cart[item] = item

you are assigning to a different key each time, because you have written 
the VARIABLE item, which changes each time through the loop. If we 
unroll the loop again, we see:

    item = 'one'
    cart[item] = item
    item = 'two'
    cart[item] = item
    item = 'three'
    cart[item] = item

But when you do this:

for item in cart_items:
    cart['item'] = something

you have written the CONSTANT 'item', which is always exactly the same 
thing: a four letter word starting with 'i', ending with 'm', with 'te' 
in the middle. It is nothing but an unfortunately coincidence that the 
value of this constant, 'item', matches the name of the variable item. 
Let's get rid of the coincidence:

for item in cart_items:
    cart['word'] = something

Unrolling the loop gives us:

    item = 'one'
    cart['word'] = item
    item = 'two'
    cart['word'] = item
    item = 'three'
    cart['word'] = item


And now hopefully it is clear what is going on! If you write this:

cart = {}
cart['word'] = 'one'
cart['word'] = 'two'
cart['word'] = 'three'

it should be clear why the end result is {'word': 'three'} rather than 
{'one': 'one', 'two': 'two', 'three': 'three'}.



-- 
Steve

From carroll at tjc.com  Tue May 17 16:16:12 2016
From: carroll at tjc.com (Terry Carroll)
Date: Tue, 17 May 2016 13:16:12 -0700 (PDT)
Subject: [Tutor] sqlite
In-Reply-To: <CAC7HCj9+EC4s3ityBhNe62LpAk6YfJs_sAahj8xLt9bbgMrBbg@mail.gmail.com>
References: <CAC7HCj9+EC4s3ityBhNe62LpAk6YfJs_sAahj8xLt9bbgMrBbg@mail.gmail.com>
Message-ID: <alpine.LRH.2.00.1605171254070.20301@aqua.rahul.net>

On Tue, 3 May 2016, Crusier wrote:

> I am just wondering if there is any good reference which I can learn how to
> program SQLITE using Python
>
> I can not find any book is correlated to Sqlite using Python.

"The Definitive Guide to SQLite" is about SQLite, but includes a chapter 
on both PySQLite and APSW for Python access. One of the book co-authors, 
Michael Owens, is the original author of PySQLite.

From esawiek at gmail.com  Tue May 17 13:11:45 2016
From: esawiek at gmail.com (Ek Esawi)
Date: Tue, 17 May 2016 13:11:45 -0400
Subject: [Tutor] genfromtxt and dtype to convert data to correct format
Message-ID: <CA+ZkTxutBQV3EP8aSc93N_SffiOHnDT2gQSREBJ=pEisCwa=wg@mail.gmail.com>

Hi All?



I am reading data from a file using genfromtxt. A part of my data (input,
output, and desired output) is shown below which consists of string,
integer, time, and date type data. I want to read the data so that the
output comes out in the correct format (the desired output as shown below).
I used converters to covert time and date values, but all came out in
string format (output below).



I tried to use structured dtype but without success and I don?t want to use
pandas. What is the best remedy to achieve the desired output shown below?



Thanks in advance?EK



++++++++++++++++++++++++++++++



Code



CF = lambda date: datetime.strptime(bytes.decode(date),
%m/%d/%Y).strftime(%Y-%m-%d)  # convert data

CF1 = lambda time: datetime.strptime(bytes.decode(time),
%H:%M).strftime(%H:%M:%S)       # convert time

MyFile=New_file



CRNs={Date: CF,Time:CF1,In:CF1,Dur:CF1,PP:CF1,Pre:CF1}
                               #converters



data = np.genfromtxt(MyFile,
names=True,delimiter=,,converters=CRNs,dtype=None)





Input



O            Date            Name           Time    Int
Dur           PP           H          Pred

312171   7/1/1995      Old              13:37   1:43        4:42
13:16      162       13:19

358237   5/25/1993    New             12:22   1:31        4:16
12:03      160       12:13



Output



[ (312171, 1995-07-01, bOld, 13:37:00, 01:43:00, 04:42:00, 13:16:00, 162,
13:19:00)

 (358237, 1993-05-25, bNew, 12:22:00, 01:31:00, 04:16:00, 12:03:00, 160,
12:13:00)]



Desired output



[ (312171, 1995-07-01, bOld, 13:37:00, 01:43:00, 04:42:00, 13:16:00, 162,
13:19:00)

 (358237, 1993-05-25, bNew, 12:22:00, 01:31:00, 04:16:00, 12:03:00, 160,
12:13:00)]

From alan.gauld at yahoo.co.uk  Wed May 18 02:44:49 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 18 May 2016 07:44:49 +0100
Subject: [Tutor] genfromtxt and dtype to convert data to correct format
In-Reply-To: <CA+ZkTxutBQV3EP8aSc93N_SffiOHnDT2gQSREBJ=pEisCwa=wg@mail.gmail.com>
References: <CA+ZkTxutBQV3EP8aSc93N_SffiOHnDT2gQSREBJ=pEisCwa=wg@mail.gmail.com>
Message-ID: <nhh30v$37r$1@ger.gmane.org>

On 17/05/16 18:11, Ek Esawi wrote:

> output comes out in the correct format (the desired output as shown below).
> I used converters to covert time and date values, but all came out in
> string format (output below).

What makes you think they are strings? I would expect to see quote signs
if they were strings but there are no quotes...

> CF = lambda date: datetime.strptime(bytes.decode(date),
> %m/%d/%Y).strftime(%Y-%m-%d)  # convert data
> 
> CF1 = lambda time: datetime.strptime(bytes.decode(time),
> %H:%M).strftime(%H:%M:%S)       # convert time

But both of these lambdas return strings (strftime)
You parse the date/time from the bytes then call strftime
on the result which returns a string.

But also you don't have quotes around your format strings
so you should get a syntax error. Please post the actual
code you are using.

> 
> MyFile=New_file
> CRNs={Date: CF,Time:CF1,In:CF1,Dur:CF1,PP:CF1,Pre:CF1}
> data = np.genfromtxt(MyFile,
>            names=True,delimiter=,,converters=CRNs,dtype=None)
> 
> Input
> O            Date            Name           Time    Int
> Dur           PP           H          Pred
> 
> 312171   7/1/1995      Old              13:37   1:43        4:42
> 13:16      162       13:19
> 
> Output
> [ (312171, 1995-07-01, bOld, 13:37:00, 01:43:00, 04:42:00, 13:16:00, 162,
> 13:19:00)
> 
> 
> Desired output
> [ (312171, 1995-07-01, bOld, 13:37:00, 01:43:00, 04:42:00, 13:16:00, 162,
> 13:19:00)

Your desired output looks exactly like the real output so it's
not clear what exactly you want to be different?


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



From esawiek at gmail.com  Wed May 18 09:14:36 2016
From: esawiek at gmail.com (Ek Esawi)
Date: Wed, 18 May 2016 09:14:36 -0400
Subject: [Tutor] genfromtxt and dtype to convert data to correct format
Message-ID: <CA+ZkTxuwct+jm1mJZoAr8GH+aPV30GVowUjdDkgZMib3Y44ifw@mail.gmail.com>

OPS! Sorry, I made a mistake on the posting. My output is in a string
format as shown below. I want the 1st and 8th integers, the 3rd string
which is OK as, the 2nd date and the rest time. I tried several
combinations of dtype but could not get the date and time data to without
the single quote -string format.




[ (b'312171', '1995-07-01', b'Old', '13:37:00', '01:43:00', '04:42:00',
'13:16:00', b'162', '13:19:00')
 (b'358237', '1993-05-25', b'Old', '12:22:00', '01:31:00', '04:16:00',
'12:03:00', b'160', '12:13:00')

From s.shall at virginmedia.com  Wed May 18 13:13:25 2016
From: s.shall at virginmedia.com (Sydney Shall)
Date: Wed, 18 May 2016 18:13:25 +0100
Subject: [Tutor] genfromtxt and dtype to convert data to correct format
In-Reply-To: <CA+ZkTxuwct+jm1mJZoAr8GH+aPV30GVowUjdDkgZMib3Y44ifw@mail.gmail.com>
References: <CA+ZkTxuwct+jm1mJZoAr8GH+aPV30GVowUjdDkgZMib3Y44ifw@mail.gmail.com>
Message-ID: <330e7411-30f4-094e-53bb-d623bb7081e1@virginmedia.com>

On 18/05/2016 14:14, Ek Esawi wrote:
> OPS! Sorry, I made a mistake on the posting. My output is in a string
> format as shown below. I want the 1st and 8th integers, the 3rd string
> which is OK as, the 2nd date and the rest time. I tried several
> combinations of dtype but could not get the date and time data to without
> the single quote -string format.
>
>
>
>
> [ (b'312171', '1995-07-01', b'Old', '13:37:00', '01:43:00', '04:42:00',
> '13:16:00', b'162', '13:19:00')
>  (b'358237', '1993-05-25', b'Old', '12:22:00', '01:31:00', '04:16:00',
> '12:03:00', b'160', '12:13:00')
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
Try the following;

line1 = [ (b'312171', '1995-07-01', b'Old', '13:37:00', '01:43:00', 
'04:42:00','13:16:00', b'162', '13:19:00')]
line2 = [(b'358237', '1993-05-25', b'Old', '12:22:00', 
'01:31:00','04:16:00','12:03:00', b'160', '12:13:00')]

item1A = line1[0][0]
item1B = line1[0][7]
item2A = line2[0][0]
item2B = line2[0][7]
print item1A, item1B
print item2A, item2B


-- 
Sydney

From esawiek at gmail.com  Wed May 18 15:11:00 2016
From: esawiek at gmail.com (Ek Esawi)
Date: Wed, 18 May 2016 15:11:00 -0400
Subject: [Tutor] genfromtxt and dtype to convert data to correct format
Message-ID: <CA+ZkTxvNsXp6B3MOyVwuwSd=y_A-PgRoB8CZOyxaYAEDAMj=Dw@mail.gmail.com>

Thanks Sydney. The print statement prints items w/o quotation marks,
but doesn't change the type. I want the datatype to be changed.

I am thinking it can eb done with astructured array dtyep but have not
been able to get to wort.

Thanks again--EK

From alan.gauld at yahoo.co.uk  Wed May 18 18:19:57 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 18 May 2016 23:19:57 +0100
Subject: [Tutor] genfromtxt and dtype to convert data to correct format
In-Reply-To: <CA+ZkTxuwct+jm1mJZoAr8GH+aPV30GVowUjdDkgZMib3Y44ifw@mail.gmail.com>
References: <CA+ZkTxuwct+jm1mJZoAr8GH+aPV30GVowUjdDkgZMib3Y44ifw@mail.gmail.com>
Message-ID: <nhipqb$hr9$1@ger.gmane.org>

On 18/05/16 14:14, Ek Esawi wrote:
> OPS! Sorry, I made a mistake on the posting. My output is in a string
> format as shown below. I want the 1st and 8th integers, the 3rd string
> which is OK as, the 2nd date and the rest time. 

You will need to convert the integers manually I suspect
with int(row[0]) and int(row[7]).

For the dates and times, what happens if you simply remove
the strftime() functions from your lambdas?

Things are complicated slightly by your use of genfromtxt since
it's part of numpy and not in the standard library. I have
no idea what it does so there may be tricks you can do with
it.

> [ (b'312171', '1995-07-01', b'Old', '13:37:00', '01:43:00', '04:42:00',
> '13:16:00', b'162', '13:19:00')


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



From esawiek at gmail.com  Wed May 18 20:31:02 2016
From: esawiek at gmail.com (Ek Esawi)
Date: Wed, 18 May 2016 20:31:02 -0400
Subject: [Tutor] genfromtxt and dtype to convert data to correct format
Message-ID: <CA+ZkTxsjtLaOhFpRUXq2b-Hx4o5MUWuo9PjV32X8PTQ4-5BzDg@mail.gmail.com>

Thanks Alan!

Taking the strtime off did not work either and printed dattime.dattime(very
long date format). I was able to get the integer and string parts fixed via
dtype,
but could not do the same for date and time. I have a feeling that
structured arrays might do the trick but don't know yet how.

Thanks again--EK

From alan.gauld at yahoo.co.uk  Thu May 19 04:37:57 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 19 May 2016 09:37:57 +0100
Subject: [Tutor] genfromtxt and dtype to convert data to correct format
In-Reply-To: <CA+ZkTxsjtLaOhFpRUXq2b-Hx4o5MUWuo9PjV32X8PTQ4-5BzDg@mail.gmail.com>
References: <CA+ZkTxsjtLaOhFpRUXq2b-Hx4o5MUWuo9PjV32X8PTQ4-5BzDg@mail.gmail.com>
Message-ID: <nhju14$ks$1@ger.gmane.org>

On 19/05/16 01:31, Ek Esawi wrote:
> Thanks Alan!
> 
> Taking the strtime off did not work either and printed dattime.dattime(very
> long date format). 

But isn't that just the representation of a datetime object (which is
what strptime produces)? In other words it's an object not a string.

Can you show us what you get back?
Or try printing the type() of the object:
eg.
print (type( row[1])
print (type( row[3])

You may be getting confused between the representation of the
object and the actual data. But until we see some actual code
and the actual output it produces it is hard to be sure.

Can you send us a cut 'n paste of an actual python session
so that we can see the parameters to genfromtxt and how
you are producing the output?

For example I'd expect something like:

>>> import datetime as dt
>>> d = dt.datetime.strptime("07/05/2015","%m/%d/%Y")
>>> t = (1,d,'foo')
>>> print(t)
(1, datetime.datetime(2015, 7, 5, 0, 0), 'foo')
>>>

Notice the middle entry is a datetime object, which is,
I think, what you want? You can get just the date (or time)
portion if you want by calling the appropriate method.
You could do that in your lambdas:

>>> CF = lambda datestr: dt.datetime.strptime(datestr,
                                              '%m/%d/%Y').date()
>>> d2 = CF('11/08/2012')
>>> data = (1,d2,'My string')
>>> print(data)
(1, datetime.date(2012, 11, 8), 'My string')
>>>

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



From crusier at gmail.com  Thu May 19 05:03:12 2016
From: crusier at gmail.com (Crusier)
Date: Thu, 19 May 2016 17:03:12 +0800
Subject: [Tutor] SQLite
Message-ID: <CAC7HCj8a3d+9G9f6xcALER=9E-5Euh+RSqLv=n65OGv4FcAnnA@mail.gmail.com>

Dear Alan,

I have read your web page and try to test thing out on SQLite.

Attached is my code:

import sqlite3
conn = sqlite3.connect('example1.db')
c = conn.cursor()
c.execute('drop table if exists stocks')
c.execute('''CREATE TABLE stocks
             (code text)''')

# Insert a row of data
List = ['00001', '00002', '00003', '00004', '00005', '00006', '00007',
'00008', '00009', '00010', '00011', '00012']

c.executemany('INSERT INTO stocks VALUES (?)', List)

# Save (commit) the changes
conn.commit()

# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
conn.close()

The following error has came out
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The
current statement uses 1, and there are 5 supplied.

Please advise.

Thank you very much.

Regards,
Crusier

From __peter__ at web.de  Thu May 19 05:20:32 2016
From: __peter__ at web.de (Peter Otten)
Date: Thu, 19 May 2016 11:20:32 +0200
Subject: [Tutor] SQLite
References: <CAC7HCj8a3d+9G9f6xcALER=9E-5Euh+RSqLv=n65OGv4FcAnnA@mail.gmail.com>
Message-ID: <nhk0h1$9et$1@ger.gmane.org>

Crusier wrote:

> Dear Alan,
> 
> I have read your web page and try to test thing out on SQLite.
> 
> Attached is my code:
> 
> import sqlite3
> conn = sqlite3.connect('example1.db')
> c = conn.cursor()
> c.execute('drop table if exists stocks')
> c.execute('''CREATE TABLE stocks
>              (code text)''')
> 
> # Insert a row of data
> List = ['00001', '00002', '00003', '00004', '00005', '00006', '00007',
> '00008', '00009', '00010', '00011', '00012']

List is a bad name; use something related to the problem domain, e. g 
stocks.

> 
> c.executemany('INSERT INTO stocks VALUES (?)', List)
> 
> # Save (commit) the changes
> conn.commit()
> 
> # We can also close the connection if we are done with it.
> # Just be sure any changes have been committed or they will be lost.
> conn.close()
> 
> The following error has came out
> sqlite3.ProgrammingError: Incorrect number of bindings supplied. The
> current statement uses 1, and there are 5 supplied.
> 
> Please advise.

The List argument is interpreted as a sequence of records and thus what you 
meant as a single value, e. g. "00001" as a sequence of fields, i. e. every 
character counts as a separate value. 

To fix the problem you can either change the list to a list of tuples or 
lists

List = [['00001'], ['00002'], ['00003'], ...]

or add a zip() call in the line

c.executemany('INSERT INTO stocks VALUES (?)', zip(List))

which has the same effect:

>>> list(zip(["foo", "bar", "baz"]))
[('foo',), ('bar',), ('baz',)]




From esawiek at gmail.com  Thu May 19 07:51:02 2016
From: esawiek at gmail.com (Ek Esawi)
Date: Thu, 19 May 2016 07:51:02 -0400
Subject: [Tutor] genfromtxt and dtype to convert data to correct format
Message-ID: <CA+ZkTxuniaNNJEcV_O_zuGLD2jyyyifyuSyu_-O-DpczBeJ_5g@mail.gmail.com>

Thanks again!

I tried a combination of the suggestions and still not getting what i want.

Here are the original code, file, and output.

CODE

mport csv; import numpy as np; from datetime import datetime, date, time

CF = lambda date: datetime.strptime(bytes.decode(date),
'%m/%d/%Y').strftime('%Y-%m-%d')
CF1 = lambda time: datetime.strptime(bytes.decode(time),
'%H:%M').strftime('%H:%M:%S')
MyFile='c:/Users/EK Esawi/My Documents/Temp/GOSA-3.csv'
CRNs={'Date':
CF,'Time':CF1,'Interval':CF1,'Duration':CF1,'Preplay':CF1,'Prediction':CF1}

data = np.genfromtxt(MyFile,
names=True,delimiter=',',converters=CRNs,dtype=None)
print(data)

INPUT

O Date Geyser Time Interval Duration Preplay Heght Prediction 312171
7/1/1995 Position 13:37 1:43 4:42 13:16 162 13:19 358237 5/25/1993 Position
12:22 1:31 4:16 12:03 160 12:13 339971 7/17/1994 Position 15:54 1:23 4:36
15:43 160 15:51

OUTPUT

[ (312171, '1995-07-01', b'Old Faithful', '13:37:00', '01:43:00',
'04:42:00', '13:16:00', 162, '13:19:00')
 (358237, '1993-05-25', b'Old Faithful', '12:22:00', '01:31:00',
'04:16:00', '12:03:00', 160, '12:13:00')
 (339971, '1994-07-17', b'Old Faithful', '15:54:00', '01:23:00',
'04:36:00', '15:43:00', 160, '15:51:00')

From craig.r.jackson at gmail.com  Thu May 19 10:11:56 2016
From: craig.r.jackson at gmail.com (Craig Jackson)
Date: Thu, 19 May 2016 09:11:56 -0500
Subject: [Tutor] FTP file transfer stops, no error given
Message-ID: <CAN4NhVwryBOo4A=6XHpiqHZgwyQ9XrWZKpUuGsauZt8W8cb-ww@mail.gmail.com>

The Python script has two objectives: a) create a web page from data
in an Excel spreadsheet, b) upload that web page to a web server using
ftp. In a nutshell the problem is that if the two objectives are
combined into one Python script, ftp stops uploading in the middle of
the file, but if the same code is split into two files, web page
creation in one script and ftp in another, and they are run
separately, ftp uploads the entire file and it all works. Below are
the details.

Script #1: Create web page
import glob, os, sys, unicodedata

imagesdirectory = 'C:\\Users\\craig\\Desktop\\Network
Drives\\Documents\\Volunteer and Nonprofit\\Peckerwood Garden\\tour
guide information\\images\\'
spreadsheet='C:\\Users\\craig\\Desktop\\Network
Drives\\Documents\\Volunteer and Nonprofit\\Peckerwood Garden\\tour
guide information\\index2.xlsx'

# load excel file and set directory variables
from openpyxl import load_workbook
wb = load_workbook(filename = spreadsheet, data_only = True)
ws = wb.get_sheet_by_name('Garden')
numberofrecords = ws.cell(row = 1, column = 1).value
htmlpage = open('C:\\Users\\craig\\Desktop\\Network
Drives\\Documents\\Volunteer and Nonprofit\\Peckerwood Garden\\tour
guide information\\index2.html', 'w')
htmlpage.write('<!DOCTYPE html><html><head><meta
charset="UTF-8"><title>Peckerwood Garden Docent Notes</title>\n')
htmlpage.write('<meta name="robots" content="noindex">')
htmlpage.write('<META NAME="ROBOTS" CONTENT="NOARCHIVE">')
htmlpage.write('<link rel=Stylesheet href="css/stylesheet.css"></head>\n')
htmlpage.write('<body>\n')
htmlpage.write('<table>\n')
htmlpage.write('<tr>\n')
htmlpage.write('<th class="uid">Unique ID</th>\n')
htmlpage.write('<th class="loc">Location</th>\n')
htmlpage.write('<th class="nam">Name</th>\n')
htmlpage.write('<th class="fam">Family</th>\n')
htmlpage.write('<th class="com">Common Name</th>\n')
htmlpage.write('<th class="nat">Nativity</th>\n')
htmlpage.write('<th class="pho">Photographs</th>\n')
htmlpage.write('<th class="des">Description</th>\n')
htmlpage.write('</tr>\n')

# loop through excel spreadsheet, search images directory, create html file
for i in range(2,numberofrecords + 2):
    uniqueid = str(ws.cell(row = i, column = 2).value)

    location = unicodedata.normalize('NFKD', ws.cell(row = i, column =
3).value).encode('ascii','ignore')

    name = unicodedata.normalize('NFKD', ws.cell(row = i, column =
4).value).encode('ascii','ignore')
    if ws.cell(row = i, column = 5).value:
        family = unicodedata.normalize('NFKD', ws.cell(row = i, column
= 5).value).encode('ascii','ignore')
    else:
        family = ""
    if ws.cell(row = i, column = 6).value:
        commonname = unicodedata.normalize('NFKD', ws.cell(row = i,
column = 6).value).encode('ascii','ignore')
    else:
        commonname = ""
    if ws.cell(row = i, column = 7).value:
        nativity = unicodedata.normalize('NFKD', ws.cell(row = i,
column = 7).value).encode('ascii','ignore')
    else:
        nativity = ""
    if ws.cell(row = i, column = 8).value:
        description = unicodedata.normalize('NFKD', ws.cell(row = i,
column = 8).value).encode('ascii','ignore')
    else:
        description = ""
    htmlpage.write('<tr>\n')
    htmlpage.write('<td class="uid">' + uniqueid + '</td>\n')
    htmlpage.write('<td class="loc">' + location + '</td>\n')
    htmlpage.write('<td class="nam">' + name + '</td>\n')
    htmlpage.write('<td class="fam">' + family + '</td>\n')
    htmlpage.write('<td class="com">' + commonname + '</td>\n')
    htmlpage.write('<td class="nat">' + nativity + '</td>\n')
    htmlpage.write('<td class="pho">')
    for x in glob.glob(imagesdirectory + uniqueid + '*'):
        htmlpage.write ('<a href=\"images/' + os.path.basename(x) +
'\">Photo</a>\n')
    htmlpage.write('</td>')
    htmlpage.write('<td class="des">' + description +'</td></tr>\n')
htmlpage.write('</table></body></html>')
htmlpage.close

Script #2: Use FTP to upload files
# open ftp and copy up web files
from ftplib import FTP
ftp = FTP('wildtrip.com','user','pass')
ftp.set_debuglevel(2)
ftp.cwd('/wildtrip.com/tour/css/')
filename = 'C:\\Users\\craig\\Desktop\\Network
Drives\\Documents\\Volunteer and Nonprofit\\Peckerwood Garden\\tour
guide information\\css\\stylesheet.css'
ftp.storlines("STOR stylesheet.css", open(filename, 'r'))
ftp.cwd('/wildtrip.com/tour/')
filename = 'C:\\Users\\craig\\Desktop\\Network
Drives\\Documents\\Volunteer and Nonprofit\\Peckerwood Garden\\tour
guide information\\index2.html'
ftp.storlines("STOR index.html", open(filename, 'r'))
ftp.quit()


Combined scripts have output as follows:

the last lines of the html file on the local disk:

<a href="images/10863 s1700065 2014-nov.jpg">Photo</a>
<a href="images/10863 s1700080 2014-nov.jpg">Photo</a>
</td><td class="des"></td></tr>
</table></body></html>


As you can see the script correctly wrote the html code to the local file.

However, ftp upload of this very same local file terminates. The last
lines of the uploaded file:

<a href="images/10863 2016-04-16 11.57.02.jpg">Photo</a>
<a href="images/10863 2016-04-16 11.58.01.jpg">Photo</a>
<a href="ima

As you can see, the upload terminated with no error. It happens 100%
of the time. It's interesting that ftp does not terminate
stylesheet.css.

If I run the scripts separately, the upload works fine.

Thanks for your help.
Craig Jackson

From alan.gauld at yahoo.co.uk  Thu May 19 12:16:17 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 19 May 2016 17:16:17 +0100
Subject: [Tutor] genfromtxt and dtype to convert data to correct format
In-Reply-To: <CA+ZkTxuniaNNJEcV_O_zuGLD2jyyyifyuSyu_-O-DpczBeJ_5g@mail.gmail.com>
References: <CA+ZkTxuniaNNJEcV_O_zuGLD2jyyyifyuSyu_-O-DpczBeJ_5g@mail.gmail.com>
Message-ID: <nhkosf$1up$1@ger.gmane.org>

On 19/05/16 12:51, Ek Esawi wrote:
> Thanks again!
> 
> I tried a combination of the suggestions and still not getting what i want.
> 
> Here are the original code, file, and output.
> 
> CODE
> 
> mport csv; import numpy as np; from datetime import datetime, date, time
> 
> CF = lambda date: datetime.strptime(bytes.decode(date),
> '%m/%d/%Y').strftime('%Y-%m-%d')

Again you have strftime at the end so it will result in a string
output. You need to remove that if you want a date/time/datetime
object as a result.

That's assuming that it is a datetime style object that you want.

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



From alan.gauld at yahoo.co.uk  Thu May 19 12:33:13 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 19 May 2016 17:33:13 +0100
Subject: [Tutor] SQLite
In-Reply-To: <CAC7HCj8a3d+9G9f6xcALER=9E-5Euh+RSqLv=n65OGv4FcAnnA@mail.gmail.com>
References: <CAC7HCj8a3d+9G9f6xcALER=9E-5Euh+RSqLv=n65OGv4FcAnnA@mail.gmail.com>
Message-ID: <nhkps7$ml6$1@ger.gmane.org>

On 19/05/16 10:03, Crusier wrote:

> c.execute('''CREATE TABLE stocks
>              (code text)''')
> 
> # Insert a row of data
> List = ['00001', '00002', '00003', '00004', '00005', '00006', '00007',
> '00008', '00009', '00010', '00011', '00012']
> 
> c.executemany('INSERT INTO stocks VALUES (?)', List)

Peter has already given you one answer, I'll repeat it in a slightly
different form. Between the two of us you will hopefully
understand... :-)

the SQL statement

INSERT INTO stocks VALUES (?)

Has a placemarker (?) that execute() or executemany()expect
a sequence to fill.  This is more obvious if you had more
than one variable:

INSERT INTO stocks VALUES (?, ?)

Here it would expect a sequence of two values.

But although you only have one value, execute() still
expects a sequence, but one that contains a single value.
You are providing strings which are sequences of 5 characters,
so exec tries to process the 5 characters but has only 1
placemarker so it fails. So you need to pass a sequence
(usually a tuple) of one value like:

('12345',)  # note the comma at the end.

execmany() is exactly the same but expects a sequence of
sequences. So you need your list to contain tuples as above

stock_codes = [('12345',), ('23456',), ...]


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



From alan.gauld at yahoo.co.uk  Thu May 19 12:37:57 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 19 May 2016 17:37:57 +0100
Subject: [Tutor] FTP file transfer stops, no error given
In-Reply-To: <CAN4NhVwryBOo4A=6XHpiqHZgwyQ9XrWZKpUuGsauZt8W8cb-ww@mail.gmail.com>
References: <CAN4NhVwryBOo4A=6XHpiqHZgwyQ9XrWZKpUuGsauZt8W8cb-ww@mail.gmail.com>
Message-ID: <nhkq53$r6t$1@ger.gmane.org>

On 19/05/16 15:11, Craig Jackson wrote:

> ftp. In a nutshell the problem is that if the two objectives are
> combined into one Python script, ftp stops uploading in the middle of
> the file, but if the same code is split into two files, web page
> creation in one script and ftp in another, and they are run
> separately, ftp uploads the entire file and it all works. Below are
> the details.

Unfortunately you seem to have sent the variation that works.
We cannot really tell what is going on unless we can see the
code that fails.

There is one possibility based on the code below...

> htmlpage.write('<!DOCTYPE html><html><head><meta
> charset="UTF-8"><title>Peckerwood Garden Docent Notes</title>\n')
> htmlpage.write('<meta name="robots" content="noindex">')
> htmlpage.write('<META NAME="ROBOTS" CONTENT="NOARCHIVE">')
> htmlpage.write('<link rel=Stylesheet href="css/stylesheet.css"></head>\n')
> htmlpage.write('<body>\n')
> htmlpage.write('<table>\n')
> htmlpage.write('<tr>\n')
> htmlpage.write('<th class="uid">Unique ID</th>\n')
> htmlpage.write('<th class="loc">Location</th>\n')
> htmlpage.write('<th class="nam">Name</th>\n')
> htmlpage.write('<th class="fam">Family</th>\n')
> htmlpage.write('<th class="com">Common Name</th>\n')
> htmlpage.write('<th class="nat">Nativity</th>\n')
> htmlpage.write('<th class="pho">Photographs</th>\n')
> htmlpage.write('<th class="des">Description</th>\n')
> htmlpage.write('</tr>\n')

Consider using triple quoted strings to save yourself a lot of typing
and to make the html easier to read.

> ...
>     htmlpage.write('</td>')
>     htmlpage.write('<td class="des">' + description +'</td></tr>\n')
> htmlpage.write('</table></body></html>')
> htmlpage.close

Note that there are no parens after close. So you do not execute the
function and the file is not closed.

If you then try to ftp the still open file that could explain the
problems you are having. Whereas if you run this as a separate script
the file will be auto-closed at the end of the script so running the
ftp separately will work..


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



From jarod_v6 at libero.it  Thu May 19 12:37:50 2016
From: jarod_v6 at libero.it (jarod_v6 at libero.it)
Date: Thu, 19 May 2016 18:37:50 +0200 (CEST)
Subject: [Tutor] Create a pivot table
Message-ID: <327049273.346621463675870458.JavaMail.httpd@webmail-60.iol.local>

Dear All!
This is my data from a file.  I want to obtain a count table how many times c11 are present for each project and Samples and  Program.

['Program', 'Sample', 'Featurename', 'Project'],
 ['A', 'A100', 'c11', 'post50'],
 ['A', 'A100', 'c12', 'post50'],
 ['A', 'A100', 'c14', 'post50'],
 ['A', 'A100', 'c67', 'post50'],
 ['A', 'A100', 'c76', 'post50'],
 ['B', 'A100', 'c11', 'post50'],
 ['B', 'A100', 'c99', 'post50'],
 ['B', 'D33', 'c33', 'post50'],
 ['B', 'D33', 'c31', 'post50'],
 ['C', 'D34', 'c32', 'post60'],
 ['C', 'D35', 'c33', 'post60'],
 ['C', 'D36', 'c11', 'post60'],
 ['C', 'D37', 'c45', 'post60'],
 ['C', 'D38', 'c36', 'post60'],
 ['C', 'D39', 'c37', 'post60']
I want to obtain pivot table with samples on columns and  program as rown and the values I want fusionwhat it is the best way to do this?thanks in advance!


From __peter__ at web.de  Thu May 19 13:19:24 2016
From: __peter__ at web.de (Peter Otten)
Date: Thu, 19 May 2016 19:19:24 +0200
Subject: [Tutor] Create a pivot table
References: <327049273.346621463675870458.JavaMail.httpd@webmail-60.iol.local>
Message-ID: <nhksit$5aq$1@ger.gmane.org>

jarod_v6--- via Tutor wrote:

> Dear All!
> This is my data from a file.  I want to obtain a count table how many
> times c11 are present for each project and Samples and  Program.
> 
> ['Program', 'Sample', 'Featurename', 'Project'],
>  ['A', 'A100', 'c11', 'post50'],
>  ['A', 'A100', 'c12', 'post50'],
>  ['A', 'A100', 'c14', 'post50'],
>  ['A', 'A100', 'c67', 'post50'],
>  ['A', 'A100', 'c76', 'post50'],
>  ['B', 'A100', 'c11', 'post50'],
>  ['B', 'A100', 'c99', 'post50'],
>  ['B', 'D33', 'c33', 'post50'],
>  ['B', 'D33', 'c31', 'post50'],
>  ['C', 'D34', 'c32', 'post60'],
>  ['C', 'D35', 'c33', 'post60'],
>  ['C', 'D36', 'c11', 'post60'],
>  ['C', 'D37', 'c45', 'post60'],
>  ['C', 'D38', 'c36', 'post60'],
>  ['C', 'D39', 'c37', 'post60']
> I want to obtain pivot table with samples on columns and  program as rown
> and the values I want fusionwhat it is the best way to do this?thanks in
> advance!

With the pivot() function from 

https://mail.python.org/pipermail/tutor/2016-April/108671.html

>>> rows = [
...  ['A', 'A100', 'c11', 'post50'],
...  ['A', 'A100', 'c12', 'post50'],
...  ['A', 'A100', 'c14', 'post50'],
...  ['A', 'A100', 'c67', 'post50'],
...  ['A', 'A100', 'c76', 'post50'],
...  ['B', 'A100', 'c11', 'post50'],
...  ['B', 'A100', 'c99', 'post50'],
...  ['B', 'D33', 'c33', 'post50'],
...  ['B', 'D33', 'c31', 'post50'],
...  ['C', 'D34', 'c32', 'post60'],
...  ['C', 'D35', 'c33', 'post60'],
...  ['C', 'D36', 'c11', 'post60'],
...  ['C', 'D37', 'c45', 'post60'],
...  ['C', 'D38', 'c36', 'post60'],
...  ['C', 'D39', 'c37', 'post60']
... ]
>>> table = pivot(rows, operator.itemgetter(1), operator.itemgetter(0), 
lambda r: r[2] == "c11")
>>> csv.writer(sys.stdout, delimiter="\t").writerows(table)
        A100    D33     D34     D35     D36     D37     D38     D39
A       1       -/-     -/-     -/-     -/-     -/-     -/-     -/-
B       1       0       -/-     -/-     -/-     -/-     -/-     -/-
C       -/-     -/-     0       0       1       0       0       0

There are probably many other options, but you should seriously consider 
using a spreadsheet application.


From craig.r.jackson at gmail.com  Thu May 19 14:01:00 2016
From: craig.r.jackson at gmail.com (Craig Jackson)
Date: Thu, 19 May 2016 13:01:00 -0500
Subject: [Tutor] FTP file transfer stops, no error given
In-Reply-To: <nhkq53$r6t$1@ger.gmane.org>
References: <CAN4NhVwryBOo4A=6XHpiqHZgwyQ9XrWZKpUuGsauZt8W8cb-ww@mail.gmail.com>
 <nhkq53$r6t$1@ger.gmane.org>
Message-ID: <CAN4NhVwWMG-XaZpDogP9R+Ce+VXTe7ctQm2snz2LZ3Zc3egufg@mail.gmail.com>

Adding the parentheses worked. So sorry for taking your time. I'm new
to Python and not at all a programmer. Thanks for your help.

On Thu, May 19, 2016 at 11:37 AM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 19/05/16 15:11, Craig Jackson wrote:
>
>> ftp. In a nutshell the problem is that if the two objectives are
>> combined into one Python script, ftp stops uploading in the middle of
>> the file, but if the same code is split into two files, web page
>> creation in one script and ftp in another, and they are run
>> separately, ftp uploads the entire file and it all works. Below are
>> the details.
>
> Unfortunately you seem to have sent the variation that works.
> We cannot really tell what is going on unless we can see the
> code that fails.
>
> There is one possibility based on the code below...
>
>> htmlpage.write('<!DOCTYPE html><html><head><meta
>> charset="UTF-8"><title>Peckerwood Garden Docent Notes</title>\n')
>> htmlpage.write('<meta name="robots" content="noindex">')
>> htmlpage.write('<META NAME="ROBOTS" CONTENT="NOARCHIVE">')
>> htmlpage.write('<link rel=Stylesheet href="css/stylesheet.css"></head>\n')
>> htmlpage.write('<body>\n')
>> htmlpage.write('<table>\n')
>> htmlpage.write('<tr>\n')
>> htmlpage.write('<th class="uid">Unique ID</th>\n')
>> htmlpage.write('<th class="loc">Location</th>\n')
>> htmlpage.write('<th class="nam">Name</th>\n')
>> htmlpage.write('<th class="fam">Family</th>\n')
>> htmlpage.write('<th class="com">Common Name</th>\n')
>> htmlpage.write('<th class="nat">Nativity</th>\n')
>> htmlpage.write('<th class="pho">Photographs</th>\n')
>> htmlpage.write('<th class="des">Description</th>\n')
>> htmlpage.write('</tr>\n')
>
> Consider using triple quoted strings to save yourself a lot of typing
> and to make the html easier to read.
>
>> ...
>>     htmlpage.write('</td>')
>>     htmlpage.write('<td class="des">' + description +'</td></tr>\n')
>> htmlpage.write('</table></body></html>')
>> htmlpage.close
>
> Note that there are no parens after close. So you do not execute the
> function and the file is not closed.
>
> If you then try to ftp the still open file that could explain the
> problems you are having. Whereas if you run this as a separate script
> the file will be auto-closed at the end of the script so running the
> ftp separately will work..
>
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From carroll at tjc.com  Thu May 19 15:34:27 2016
From: carroll at tjc.com (Terry Carroll)
Date: Thu, 19 May 2016 12:34:27 -0700 (PDT)
Subject: [Tutor] Getting started in testing
Message-ID: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>

Is anyone aware of any good tutorials on testing one's Python code?

These days, I'm a hobby programmer, writing little things just for my own 
use, and don't really sweat testing much. But I do have one niche 
open-source project where I need to be a bit more regimented, and 
specifically need to develop a set of tests to be passed before releasing.

Any resources would be helpful. I am aware of the docs on unittest, but 
I'm looking for a more tutorial approach.

I use Python 2.7, and my project is a module with no GUI, if that matters. 
Thanks.

From alan.gauld at yahoo.co.uk  Thu May 19 16:46:10 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 19 May 2016 21:46:10 +0100
Subject: [Tutor] FTP file transfer stops, no error given
In-Reply-To: <CAN4NhVwWMG-XaZpDogP9R+Ce+VXTe7ctQm2snz2LZ3Zc3egufg@mail.gmail.com>
References: <CAN4NhVwryBOo4A=6XHpiqHZgwyQ9XrWZKpUuGsauZt8W8cb-ww@mail.gmail.com>
 <nhkq53$r6t$1@ger.gmane.org>
 <CAN4NhVwWMG-XaZpDogP9R+Ce+VXTe7ctQm2snz2LZ3Zc3egufg@mail.gmail.com>
Message-ID: <nhl8mg$a3n$1@ger.gmane.org>

On 19/05/16 19:01, Craig Jackson wrote:
> Adding the parentheses worked. So sorry for taking your time. I'm new
> to Python and not at all a programmer. Thanks for your help.

No trouble, that's what the list is here for.

Just remember next time to post the code that fails
rather than the code that works, it saves us guessing :-)

And if you do get error messages always post the entire
message, don't summarize it.

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



From alan.gauld at yahoo.co.uk  Thu May 19 16:49:20 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Thu, 19 May 2016 21:49:20 +0100
Subject: [Tutor] Getting started in testing
In-Reply-To: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>
References: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>
Message-ID: <nhl8se$ftb$1@ger.gmane.org>

On 19/05/16 20:34, Terry Carroll wrote:
> Is anyone aware of any good tutorials on testing one's Python code?

I'm not a big fan of video tutorials but I recently had to teach
myself Junit testing (and mockito) in Java and I found that
Youtube videos really helped. I know there are similar videos
on Python's unittest (as well as alternatives such as nose).

So a Youtube search might be a good start.
And since most are only 10 minutes or so long you won't
waste much time if you decide they aren't working for you.


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



From crusier at gmail.com  Thu May 19 20:57:30 2016
From: crusier at gmail.com (Crusier)
Date: Fri, 20 May 2016 08:57:30 +0800
Subject: [Tutor] Tutor Digest, Vol 147, Issue 30
In-Reply-To: <mailman.11.1463673602.27148.tutor@python.org>
References: <mailman.11.1463673602.27148.tutor@python.org>
Message-ID: <CAC7HCj90btGr0DEuC1XCCyjWE6TMi4dPV9K4=WSebr4aPhdv8w@mail.gmail.com>

Dear Peter & Alan,

Thanks alot. Have a great day

Cheers,
Hank

On Fri, May 20, 2016 at 12:00 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: SQLite (Peter Otten)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Thu, 19 May 2016 11:20:32 +0200
> From: Peter Otten <__peter__ at web.de>
> To: tutor at python.org
> Subject: Re: [Tutor] SQLite
> Message-ID: <nhk0h1$9et$1 at ger.gmane.org>
> Content-Type: text/plain; charset="ISO-8859-1"
>
> Crusier wrote:
>
>> Dear Alan,
>>
>> I have read your web page and try to test thing out on SQLite.
>>
>> Attached is my code:
>>
>> import sqlite3
>> conn = sqlite3.connect('example1.db')
>> c = conn.cursor()
>> c.execute('drop table if exists stocks')
>> c.execute('''CREATE TABLE stocks
>>              (code text)''')
>>
>> # Insert a row of data
>> List = ['00001', '00002', '00003', '00004', '00005', '00006', '00007',
>> '00008', '00009', '00010', '00011', '00012']
>
> List is a bad name; use something related to the problem domain, e. g
> stocks.
>
>>
>> c.executemany('INSERT INTO stocks VALUES (?)', List)
>>
>> # Save (commit) the changes
>> conn.commit()
>>
>> # We can also close the connection if we are done with it.
>> # Just be sure any changes have been committed or they will be lost.
>> conn.close()
>>
>> The following error has came out
>> sqlite3.ProgrammingError: Incorrect number of bindings supplied. The
>> current statement uses 1, and there are 5 supplied.
>>
>> Please advise.
>
> The List argument is interpreted as a sequence of records and thus what you
> meant as a single value, e. g. "00001" as a sequence of fields, i. e. every
> character counts as a separate value.
>
> To fix the problem you can either change the list to a list of tuples or
> lists
>
> List = [['00001'], ['00002'], ['00003'], ...]
>
> or add a zip() call in the line
>
> c.executemany('INSERT INTO stocks VALUES (?)', zip(List))
>
> which has the same effect:
>
>>>> list(zip(["foo", "bar", "baz"]))
> [('foo',), ('bar',), ('baz',)]
>
>
>
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> https://mail.python.org/mailman/listinfo/tutor
>
>
> ------------------------------
>
> End of Tutor Digest, Vol 147, Issue 30
> **************************************

From dyoo at hashcollision.org  Thu May 19 23:15:45 2016
From: dyoo at hashcollision.org (Danny Yoo)
Date: Thu, 19 May 2016 20:15:45 -0700
Subject: [Tutor] Getting started in testing
In-Reply-To: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>
References: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>
Message-ID: <CAGZAPF45v2TuQDth6PnfAN6iOkvQPSAc5aisvrKDz5_y3N6AVg@mail.gmail.com>

On Thu, May 19, 2016 at 12:34 PM, Terry Carroll <carroll at tjc.com> wrote:
> Is anyone aware of any good tutorials on testing one's Python code?
>
> These days, I'm a hobby programmer, writing little things just for my own
> use, and don't really sweat testing much. But I do have one niche
> open-source project where I need to be a bit more regimented, and
> specifically need to develop a set of tests to be passed before releasing.
>
> Any resources would be helpful. I am aware of the docs on unittest, but I'm
> looking for a more tutorial approach.


Hi Terry,

The section on Unit Testing in Dive Into Python:

    http://www.diveintopython.net/unit_testing/

I have fond memories of "Test Driven Development: By Example" by Kent
Beck, so that might be worth looking into.

From jarod_v6 at libero.it  Fri May 20 07:13:18 2016
From: jarod_v6 at libero.it (jarod_v6 at libero.it)
Date: Fri, 20 May 2016 13:13:18 +0200 (CEST)
Subject: [Tutor] R: Re: Create a pivot table (Peter Otten)
Message-ID: <1149552750.559391463742798753.JavaMail.httpd@webmail-60.iol.local>

Thanks s much for  the help. I want to obtain table like this:


>csv.writer(sys.stdout, delimiter="\t").writerows(table)
>        A100    D33     D34     D35     D36     D37     D38     D39
>A       5         0 ...
>B       2         2  ...
>C      0  ..
>
I have tried the pandas way but unfortunately there is many duplicates . So 
Now I move to create a new file using dictionary  and  a file with this format.

('A', A100') 5
('B', 'A100) 2

I just wondering if there is a pythonic way to do this. I don't want to use 
another software if I can


From __peter__ at web.de  Fri May 20 08:41:28 2016
From: __peter__ at web.de (Peter Otten)
Date: Fri, 20 May 2016 14:41:28 +0200
Subject: [Tutor] Create a pivot table
References: <1149552750.559391463742798753.JavaMail.httpd@webmail-60.iol.local>
Message-ID: <nhn0lp$qoc$1@ger.gmane.org>

jarod_v6--- via Tutor wrote:

Please address your posts to the whole list, not me specifically. I might 
read them all the same. 

Thank you.

> Thanks s much for  the help. I want to obtain table like this:
> 
> 
>>csv.writer(sys.stdout, delimiter="\t").writerows(table)
>>        A100    D33     D34     D35     D36     D37     D38     D39
>>A       5         0 ...
>>B       2         2  ...
>>C      0  ..
>>
> I have tried the pandas way but unfortunately there is many duplicates .

Please show your code in a small self-contained example, 
the output it produces, and what exact output you want instead.
Then one of us (not necessarily me) might be able to help you fix it.

> So
> Now I move to create a new file using dictionary  and  a file with this
> format.
> 
> ('A', A100') 5
> ('B', 'A100) 2
> 
> I just wondering if there is a pythonic way to do this. 

"Pythonic" is elegant idiomatic Python. At this stage I'd settle for 
anything that works. Just saying...

> I don't want to use another software if I can

$ cat pivot_demo2.py
import csv
import operator
import sys
from pivot import pivot

data = {
    ("A", "A100"): 5,
    ("B", "A100"): 2,
    ("B", "D33"): 2,
}

table = pivot(
    data,
    operator.itemgetter(1),
    operator.itemgetter(0),
    lambda k, data=data: data[k],
    empty=0)
csv.writer(sys.stdout, delimiter="\t").writerows(table)
$ python3 pivot_demo2.py
        A100    D33
A       5       0
B       2       2
$ 



From esawiek at gmail.com  Fri May 20 08:55:32 2016
From: esawiek at gmail.com (Ek Esawi)
Date: Fri, 20 May 2016 08:55:32 -0400
Subject: [Tutor] genfromtxt and dtype to convert data to correct format
Message-ID: <CA+ZkTxuW_Y7YOJk=xu9qsVi=gg-mFTULMHA4OhLvZSLso0kapw@mail.gmail.com>

Thanks again Alan for your help and patience. Your earlier suggestion
works; i just now realized that the output was indeed correct. Thanks
again--EK

From michael.selik at gmail.com  Fri May 20 11:12:39 2016
From: michael.selik at gmail.com (Michael Selik)
Date: Fri, 20 May 2016 15:12:39 +0000
Subject: [Tutor] Create a pivot table
In-Reply-To: <nhn0lp$qoc$1@ger.gmane.org>
References: <1149552750.559391463742798753.JavaMail.httpd@webmail-60.iol.local>
 <nhn0lp$qoc$1@ger.gmane.org>
Message-ID: <CAGgTfkOzB5z94srRULw4yVtM09UdD2X2zEgqg757QgrGApG1Xg@mail.gmail.com>

On Fri, May 20, 2016 at 8:42 AM Peter Otten <__peter__ at web.de> wrote:

> jarod_v6--- via Tutor wrote:
> > I have tried the pandas way but unfortunately there is many duplicates .
>
> Please show your code in a small self-contained example,
> the output it produces, and what exact output you want instead.
> Then one of us (not necessarily me) might be able to help you fix it.
>

I haven't seen an Pandas code, yet. What's the error message and traceback?

From michael.selik at gmail.com  Fri May 20 12:16:06 2016
From: michael.selik at gmail.com (Michael Selik)
Date: Fri, 20 May 2016 16:16:06 +0000
Subject: [Tutor] R: Re: Create a pivot table (Peter Otten)
In-Reply-To: <1149552750.559391463742798753.JavaMail.httpd@webmail-60.iol.local>
References: <1149552750.559391463742798753.JavaMail.httpd@webmail-60.iol.local>
Message-ID: <CAGgTfkMjfgncTF+dY+LV1u+pfLSqNye4pjfA+ZFURezXB+2vCQ@mail.gmail.com>

On Fri, May 20, 2016 at 7:16 AM jarod_v6--- via Tutor <tutor at python.org>
wrote:

> Thanks s much for  the help. I want to obtain table like this:
>
>
> >csv.writer(sys.stdout, delimiter="\t").writerows(table)
> >        A100    D33     D34     D35     D36     D37     D38     D39
> >A       5         0 ...
> >B       2         2  ...
> >C      0  ..
> >
> I have tried the pandas way but unfortunately there is many duplicates.
>

If pandas is raising an error, it's possible a "pivot" is not what you
want. What's the code you tried? What's the error message?

From maxjegers at gmail.com  Fri May 20 21:21:06 2016
From: maxjegers at gmail.com (Max Jegers)
Date: Fri, 20 May 2016 19:21:06 -0600
Subject: [Tutor] What these Python user-defined functions do?
Message-ID: <CANdyN1mjnxX3T2GBTO9fpL1nmOUxBWS-9tA7DOaSeFJUHFdFfQ@mail.gmail.com>

Hi,

I started learning Python (v3.5) and was given some code samples to assist
in my studies. There are some things I could not figure out using Python
documentation or other online sources. I have experience with SQL
programming and some procedural programming, but little in terms of OOP.



I try to slice and dice a Python script that exports a shipment from ERP
system to a text file.

Shipment consists of a Header (H, one record) and Details (D, one or more
records).



Script first imports a library with a number of user-defined functions.
Then the script uses functions defined in library to do exporting to a text
file.

Here is the part of the library:


class View:

def __init__(self):

              self.handle = None

?

def order(self, n):

              return hostviewOrder(handle, self.handle, n)



def put(self, fieldName, value, verify=1):

              if verify == True:

                     verify = 1

              elif verify == False:

                     verify = 0

              return hostviewPut(handle, self.handle, fieldName, value,
verify)



def read(self):

              return hostviewRead(handle, self.handle)



def browse(self, filter="", ascending=1):

              if ascending == True:

                     ascending = 1

              elif ascending == False:

                     ascending = 0

              return hostviewBrowse(handle, self.handle, filter, ascending)



def fetch(self):

              return hostviewFetch(handle, self.handle)



Here is a part of the script I am trying to understand:

def ExportShipment():

         f = open("c:\\" + me.get("SHN") + ".txt", "w")

         h = View("Header", *1*)

         d = View("Details", *1*)

         h.*order*(1) # SHN

         h.*put*("SHN", me.get("SHN"), 1)

         h.*read*()

         f.write("H," + h.get("LOCATION") + "," + h.get("ADDR1") + "\n")

         d.*browse*("SHIUNIQ=" + "{:.0f}".format(h.get("SHIUNIQ")), 1)

         while (d.*fetch*() == 0):

                 f.write("D," + d.get("ITEM") + "," +
"{:.0f}".format(d.get("QTYSHIPPED")) + "\n")

         f.close()



Export output looks like:

H,4,1234 Any Road

D,A2,1

D,B1,3


I understand what file operations do. However I can?t get what these
functions do:

*order(), put(), read(), browse(), fetch()*.


Function definitions in the library are of little help for now, as all
functions feature handle and self.handle in their returns; however I cannot
find out what handle and self.handle may mean in this context.



Please let me know if I should provide more info for my question to make
sense.



Thanks a lot!

--

From alan.gauld at yahoo.co.uk  Sat May 21 04:59:31 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sat, 21 May 2016 09:59:31 +0100
Subject: [Tutor] What these Python user-defined functions do?
In-Reply-To: <CANdyN1mjnxX3T2GBTO9fpL1nmOUxBWS-9tA7DOaSeFJUHFdFfQ@mail.gmail.com>
References: <CANdyN1mjnxX3T2GBTO9fpL1nmOUxBWS-9tA7DOaSeFJUHFdFfQ@mail.gmail.com>
Message-ID: <nhp81h$384$1@ger.gmane.org>

On 21/05/16 02:21, Max Jegers wrote:

> class View:
> 	def __init__(self):
>               self.handle = None
> 
> 	def order(self, n):
>               return hostviewOrder(handle, self.handle, n)
> 
> 	def put(self, fieldName, value, verify=1):
>               if verify == True:
>                      verify = 1
>               elif verify == False:
>                      verify = 0
>               return hostviewPut(handle, self.handle, fieldName, value,
> verify)


This is a very odd function.
The if/else bit at the top makes no sense at all.

> 	def read(self):
>               return hostviewRead(handle, self.handle)
> 
> 	def browse(self, filter="", ascending=1):
>               if ascending == True:
>                      ascending = 1
>               elif ascending == False:
>                      ascending = 0
>               return hostviewBrowse(handle, self.handle, filter, ascending)

Same comment regarding the if/else here.

> 	def fetch(self):
>               return hostviewFetch(handle, self.handle)

Other than the if/else issues above the methods are just
wrappers around the hostview library, which we obviously
can't see so can't comment on.

I also notice that self.handle never gets set to anything
other than None, which is odd unless there are other methods
you are not showing us? Also a handle argument is passed to
the hostview functions but its not clear where that is defined...

> Here is a part of the script I am trying to understand:
> 
> def ExportShipment():
>          f = open("c:\\" + me.get("SHN") + ".txt", "w")
>          h = View("Header", *1*)
>          d = View("Details", *1*)
>          h.*order*(1) # SHN
>          h.*put*("SHN", me.get("SHN"), 1)
>          h.*read*()
>          f.write("H," + h.get("LOCATION") + "," + h.get("ADDR1") + "\n")

I'm not sure where all the * characters are coming from,
I assume they are not part of the code?
But the code above opens a file and creates two View objects, one for
the header and one for the details. However the View init() function
above does not have any paramaters so this should fail. Also there is
reference to a get() method which is not part of the class definition
above. And there is reference to a me object but its not defined above
either.


>          d.*browse*("SHIUNIQ=" + "{:.0f}".format(h.get("SHIUNIQ")), 1)
>          while (d.*fetch*() == 0):
>                  f.write("D," + d.get("ITEM") + "," +
> "{:.0f}".format(d.get("QTYSHIPPED")) + "\n")
>          f.close()

Again this code does not match the code above. There is no View.get()
method. And View.browse() does not change the View's state so its hard
to see what the get() method could return. It could only work if there
were either a lot of global variables being used in the background(by
listview) or if thee is a lot more to the View definition than we have seen.

> I understand what file operations do. However I can?t get what these
> functions do:
> 
> *order(), put(), read(), browse(), fetch()*.

They are trivial wrappers around the listviewXXX functions
that are presumably defined in another library somewhere.
But the code is generally inconsistent and definitely
not good Python on any level.

> Function definitions in the library are of little help for now, as all
> functions feature handle and self.handle in their returns; however I cannot
> find out what handle and self.handle may mean in this context.

> Please let me know if I should provide more info for my question to make
> sense.

Apart from the issue over handle its not clear what you don't
understand. However until you get the two code segments
harmonised you will never make sense of it. The code as it
stands is inconsistent and could never work.


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



From sjeik_appie at hotmail.com  Sat May 21 17:51:46 2016
From: sjeik_appie at hotmail.com (Albert-Jan Roskam)
Date: Sat, 21 May 2016 21:51:46 +0000
Subject: [Tutor] Getting started in testing
In-Reply-To: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>
References: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>
Message-ID: <DUB123-W45712925E0CC6CACF43A7A834C0@phx.gbl>

(sorry for top-posting)

I liked https://www.packtpub.com/application-development/python-testing-beginners-guide though perhaps it was a bit too basic. It covers forest, unit test, nose.

> Date: Thu, 19 May 2016 12:34:27 -0700
> From: carroll at tjc.com
> To: tutor at python.org
> Subject: [Tutor] Getting started in testing
> 
> Is anyone aware of any good tutorials on testing one's Python code?
> 
> These days, I'm a hobby programmer, writing little things just for my own 
> use, and don't really sweat testing much. But I do have one niche 
> open-source project where I need to be a bit more regimented, and 
> specifically need to develop a set of tests to be passed before releasing.
> 
> Any resources would be helpful. I am aware of the docs on unittest, but 
> I'm looking for a more tutorial approach.
> 
> I use Python 2.7, and my project is a module with no GUI, if that matters. 
> Thanks.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
 		 	   		  

From usaidov at gmail.com  Sat May 21 14:34:20 2016
From: usaidov at gmail.com (Saidov)
Date: Sat, 21 May 2016 13:34:20 -0500
Subject: [Tutor] Python 3: string to decimal conversion
Message-ID: <CA+SNFKwZdk3VxVu-q4qY+Cz=Hd0jMozEn5UDVZ3t+qS7G-B4OA@mail.gmail.com>

Hello all,

I am working on a piece of python code that's supposed to help me manage a
budget:

1. Read a banking statement
2. Categorize expenses and income by month and by type
3. Print out a report comparing the projected expenses/income with actual
numbers.

*File characteristics:*
Banking statement in a csv file format.
contents: 5 columns, 1st column= date, 4 column=expenses
date format: mm/dd/yyyy, type: string
expenses format: ($0.00), type: string
income format: $0.00, type: string


*Python Version: 3.5 (64 bit)*
IDE:Microsoft Visual Studio Community 2015
Version 14.0.25123.00 Update 2

Python Tools for Visual Studio   2.2.40315.00
Python Tools for Visual Studio provides IntelliSense, projects, templates,
Interactive windows, and other support for Python developers.


*Problem:*
 I want to convert expense/income values into a decimal form so I could sum
them into appropriate buckets according to the month in which they occur. I
am getting the following error message when I run my code:

"decimal.InvalidOperation was unhandled by user code
Message: [<class 'decimal.ConversionSyntax'>]"

*Question: *I tried looking up the meaning of this error, but couldn't find
anything on the internet. *Can someone help me understand what's wrong with
my code?*

Below is my code:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
import numpy as np
import csv
import timestring as ts
import decimal

months= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
expenses = {x: decimal.Decimal() for x in months}
income = {x: decimal.Decimal() for x in months}

exp_cat = []
income_cat = []

files =['export.csv']

with open("budgetfile.csv","wt") as fw:
    writer = csv.writer(fw)
    for file in files:
        with open(file) as csvfile:
            records = csv.reader(csvfile, quoting=csv.QUOTE_NONE)
            print("Processing file {}. \n" .format(file))
            header = next(records)
            for row in records:
                row[4].replace("($","")
                row[4].replace(")","")
                row[4].replace('"', '')

                try:
                    expenses[ts.Date(row[0]).month] +=
decimal.Decimal(row[4])

                except ValueError:
                    pass
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

From ben+python at benfinney.id.au  Sat May 21 21:10:36 2016
From: ben+python at benfinney.id.au (Ben Finney)
Date: Sun, 22 May 2016 11:10:36 +1000
Subject: [Tutor] Never need to apologise for top-posting: just don't do it
 (was: Getting started in testing)
References: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>
 <DUB123-W45712925E0CC6CACF43A7A834C0@phx.gbl>
Message-ID: <854m9qc2yb.fsf_-_@benfinney.id.au>

Albert-Jan Roskam <sjeik_appie at hotmail.com> writes:

> (sorry for top-posting)

If you know enough to apologise for the mistake, you know enough to
avoid the mistake. Resist that urge.

Delay the response until you can compose it on a device that makes it
feasible to reply interleaved.

-- 
 \     ?I have an answering machine in my car. It says, ?I'm home now. |
  `\  But leave a message and I'll call when I'm out.?? ?Steven Wright |
_o__)                                                                  |
Ben Finney


From ben+python at benfinney.id.au  Sat May 21 21:16:16 2016
From: ben+python at benfinney.id.au (Ben Finney)
Date: Sun, 22 May 2016 11:16:16 +1000
Subject: [Tutor] Getting started in testing
References: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>
Message-ID: <85ziriao4f.fsf@benfinney.id.au>

Terry Carroll <carroll at tjc.com> writes:

> Is anyone aware of any good tutorials on testing one's Python code?
>
> Any resources would be helpful. I am aware of the docs on unittest,
> but I'm looking for a more tutorial approach.

The book Dive Into Python (available both for Python 2 and Python 3)
<URL:http://www.diveintopython.net/> has a good ?dive in?, tutorial
style, to unit testing a complete program.

This guide has good ?dos and don'ts? for testing while you code
<URL:http://docs.python-guide.org/en/latest/writing/tests/>.

Test behaviour of the whole program, too, with behavioural tests
<URL:https://semaphoreci.com/community/tutorials/getting-started-with-behavior-testing-in-python-with-behave>.

Automate all of this by writing build scripts which run *all* the tests
with a single command. That's something you should already have in
place, but Fabric is a place to start, or you may be more comfortable
with Make.

-- 
 \        ?The problem with television is that the people must sit and |
  `\    keep their eyes glued on a screen: the average American family |
_o__)                 hasn't time for it.? ?_The New York Times_, 1939 |
Ben Finney


From ben+python at benfinney.id.au  Sat May 21 21:19:30 2016
From: ben+python at benfinney.id.au (Ben Finney)
Date: Sun, 22 May 2016 11:19:30 +1000
Subject: [Tutor] Python 3: string to decimal conversion
References: <CA+SNFKwZdk3VxVu-q4qY+Cz=Hd0jMozEn5UDVZ3t+qS7G-B4OA@mail.gmail.com>
Message-ID: <85vb26anz1.fsf@benfinney.id.au>

Saidov <usaidov at gmail.com> writes:

> *Python Version: 3.5 (64 bit)*
> IDE:Microsoft Visual Studio Community 2015

Your IDE is apparently suppressing, or hiding somewhere, the full
traceback of the exception. It's important that you always have that in
front of you when trying to diagnose an un-handled exception.

> "decimal.InvalidOperation was unhandled by user code
> Message: [<class 'decimal.ConversionSyntax'>]"

So, this tells us only the name of the exception, not the location in
the code, nor the call stack that produced it. You need to find and
paste the full traceback text.

> *Question: *I tried looking up the meaning of this error, but couldn't find
> anything on the internet. *Can someone help me understand what's wrong with
> my code?*

Please turn off any ?rich? or HTML formatting of your message, post in
plain text only. You need the text of your message to survive without
any mangling.

-- 
 \       ?Give a man a fish, and you'll feed him for a day; give him a |
  `\    religion, and he'll starve to death while praying for a fish.? |
_o__)                                                       ?Anonymous |
Ben Finney


From cs at zip.com.au  Sat May 21 23:31:39 2016
From: cs at zip.com.au (cs at zip.com.au)
Date: Sun, 22 May 2016 13:31:39 +1000
Subject: [Tutor] Python 3: string to decimal conversion
In-Reply-To: <CA+SNFKwZdk3VxVu-q4qY+Cz=Hd0jMozEn5UDVZ3t+qS7G-B4OA@mail.gmail.com>
References: <CA+SNFKwZdk3VxVu-q4qY+Cz=Hd0jMozEn5UDVZ3t+qS7G-B4OA@mail.gmail.com>
Message-ID: <20160522033139.GA53172@cskk.homeip.net>

Hi Saidov,

I'm going to reply to your post inline, as that is the etiquette here and in 
many technical mailing lists.

On 21May2016 13:34, Saidov <usaidov at gmail.com> wrote:
>I am working on a piece of python code that's supposed to help me manage a
>budget:
>1. Read a banking statement
>2. Categorize expenses and income by month and by type
>3. Print out a report comparing the projected expenses/income with actual
>numbers.

Thank you for providing your problem's context.

>*File characteristics:*
>Banking statement in a csv file format.
>contents: 5 columns, 1st column= date, 4 column=expenses
>date format: mm/dd/yyyy, type: string
>expenses format: ($0.00), type: string
>income format: $0.00, type: string
>
>*Python Version: 3.5 (64 bit)*
>IDE:Microsoft Visual Studio Community 2015
>Version 14.0.25123.00 Update 2
>
>Python Tools for Visual Studio   2.2.40315.00
>Python Tools for Visual Studio provides IntelliSense, projects, templates,
>Interactive windows, and other support for Python developers.

And this level of detail is very welcome.

>*Problem:*
> I want to convert expense/income values into a decimal form so I could sum
>them into appropriate buckets according to the month in which they occur. I
>am getting the following error message when I run my code:
>
>"decimal.InvalidOperation was unhandled by user code
>Message: [<class 'decimal.ConversionSyntax'>]"

Please always provide the full traceback which accompanied the exception 
report; there should be a list of code lines indicating the call stack where 
the error occurred. This provides valuable context for figuring out where in 
your code to look for issues.

Absent that context, I will have a guess at where this might be occurring:

[...]
>files =['export.csv']
>with open("budgetfile.csv","wt") as fw:
>    writer = csv.writer(fw)
>    for file in files:
>        with open(file) as csvfile:
>            records = csv.reader(csvfile, quoting=csv.QUOTE_NONE)
[...]
>            for row in records:
[...]
>                try:
>                    expenses[ts.Date(row[0]).month] += decimal.Decimal(row[4])
>                except ValueError:
>                    pass

I would guess that this:

  decimal.Decimal(row[4])

is the source of your error; it seems to be the only place where you actually 
convert a string into a Decimal. I would guess that when handed a bad string 
this raises decimal.ConversionSyntax instead of a ValueError.

I suggest that you print out the value of row[4] before the "try" statement:

  print("row[4] =", repr(row[4]))

Note the use of repr: it gets you better detail about the value of the string.

Thank you for a well presented question.

Finally, please try to post in plain text instead of rich text; this is a plain 
text list and if you post in rich text or HTML (a) some hinting you have have 
povided like coloured text will not be presented to readers and (b) some 
things, particularly code, and be presented visually mangled, which makes 
things hard to read and debug.

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

From steve at pearwood.info  Sun May 22 04:16:33 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Sun, 22 May 2016 18:16:33 +1000
Subject: [Tutor] Python 3: string to decimal conversion
In-Reply-To: <CA+SNFKwZdk3VxVu-q4qY+Cz=Hd0jMozEn5UDVZ3t+qS7G-B4OA@mail.gmail.com>
References: <CA+SNFKwZdk3VxVu-q4qY+Cz=Hd0jMozEn5UDVZ3t+qS7G-B4OA@mail.gmail.com>
Message-ID: <20160522081632.GQ12028@ando.pearwood.info>

On Sat, May 21, 2016 at 01:34:20PM -0500, Saidov wrote:

> "decimal.InvalidOperation was unhandled by user code
> Message: [<class 'decimal.ConversionSyntax'>]"
> 
> *Question: *I tried looking up the meaning of this error, but couldn't find
> anything on the internet. *Can someone help me understand what's wrong with
> my code?*

https://duckduckgo.com/html/?q=decimal+InvalidOperation+python

will take you to the docs for Python 2. Changing the URL to version 3 
gives us:

https://docs.python.org/3/library/decimal.html

and searching for InvalidOperation gives us:

https://docs.python.org/3/library/decimal.html#decimal.InvalidOperation

which is not a lot of help as it only lists *some* of the things which 
will lead to that error, but we can try it at the interactive 
interpreter:

py> import decimal
py> decimal.Decimal("25")
Decimal('25')
py> decimal.Decimal("25x")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]


So the problem here is that when you call Decimal() with an invalid 
argument, you are expecting a ValueError, but Python raises 
decimal.InvalidOperation instead:

>                 try:
>                     expenses[ts.Date(row[0]).month] += decimal.Decimal(row[4])
>                 except ValueError:
>                     pass


-- 
Steve

From usaidov at gmail.com  Sun May 22 09:19:19 2016
From: usaidov at gmail.com (US)
Date: Sun, 22 May 2016 08:19:19 -0500
Subject: [Tutor] Python 3: string to decimal conversion
In-Reply-To: <20160522033139.GA53172@cskk.homeip.net>
References: <CA+SNFKwZdk3VxVu-q4qY+Cz=Hd0jMozEn5UDVZ3t+qS7G-B4OA@mail.gmail.com>
 <20160522033139.GA53172@cskk.homeip.net>
Message-ID: <CABYxsxvkRJ8haVJbnq63t=BwpCH+hvYiRYtzL6g2OzUwwzrwWw@mail.gmail.com>

Thank you all for the useful feedback. I am new to programming so bear
with me while I learn the rules...


I have run Cameron's code to print the values and have the traceback
results. please see below.



-----Original Message-----
From: cs at zip.com.au [mailto:cs at zip.com.au]
Sent: Saturday, May 21, 2016 10:32 PM
To: Saidov <usaidov at gmail.com>
Cc: tutor at python.org
Subject: Re: [Tutor] Python 3: string to decimal conversion

Hi Saidov,

I'm going to reply to your post inline, as that is the etiquette here and
in many technical mailing lists.

On 21May2016 13:34, Saidov <usaidov at gmail.com> wrote:
>I am working on a piece of python code that's supposed to help me
>manage a
>budget:
>1. Read a banking statement
>2. Categorize expenses and income by month and by type 3. Print out a
>report comparing the projected expenses/income with actual numbers.

Thank you for providing your problem's context.

>*File characteristics:*
>Banking statement in a csv file format.
>contents: 5 columns, 1st column= date, 4 column=expenses date format:
>mm/dd/yyyy, type: string expenses format: ($0.00), type: string income
>format: $0.00, type: string
>
>*Python Version: 3.5 (64 bit)*
>IDE:Microsoft Visual Studio Community 2015 Version 14.0.25123.00 Update
>2
>
>Python Tools for Visual Studio   2.2.40315.00
>Python Tools for Visual Studio provides IntelliSense, projects,
>templates, Interactive windows, and other support for Python developers.

And this level of detail is very welcome.

>*Problem:*
> I want to convert expense/income values into a decimal form so I could
>sum them into appropriate buckets according to the month in which they
>occur. I am getting the following error message when I run my code:
>
>"decimal.InvalidOperation was unhandled by user code
>Message: [<class 'decimal.ConversionSyntax'>]"

Please always provide the full traceback which accompanied the exception
report; there should be a list of code lines indicating the call stack
where the error occurred. This provides valuable context for figuring out
where in your code to look for issues.

Absent that context, I will have a guess at where this might be occurring:

[...]
>files =['export.csv']
>with open("budgetfile.csv","wt") as fw:
>    writer = csv.writer(fw)
>    for file in files:
>        with open(file) as csvfile:
>            records = csv.reader(csvfile, quoting=csv.QUOTE_NONE)
[...]
>            for row in records:
[...]
>                try:
>                    expenses[ts.Date(row[0]).month] +=
decimal.Decimal(row[4])
>                except ValueError:
>                    pass

I would guess that this:

  decimal.Decimal(row[4])

is the source of your error; it seems to be the only place where you
actually convert a string into a Decimal. I would guess that when handed a
bad string this raises decimal.ConversionSyntax instead of a ValueError.

I suggest that you print out the value of row[4] before the "try"
statement:

  print("row[4] =", repr(row[4]))

Note the use of repr: it gets you better detail about the value of the
string.

Thank you for a well presented question.

Finally, please try to post in plain text instead of rich text; this is a
plain text list and if you post in rich text or HTML (a) some hinting you
have have povided like coloured text will not be presented to readers and
(b) some things, particularly code, and be presented visually mangled,
which makes things hard to read and debug.

---------------------------------
+ decimal <module 'decimal' from 'C:\mypath\Anaconda3\\lib\\decimal.py'> module
+ expenses {1: Decimal('0'), 2: Decimal('0'), 3: Decimal('0'), 4:
Decimal('0'), 5: Decimal('0'), 6: Decimal('0'), 7: Decimal('0'), 8:
Decimal('0'), 9: Decimal('0'), 10: Decimal('0'), 11: Decimal('0'), 12:
Decimal('0')} dict
row[0] '"1/1/2016"' str
row[4] '""' str
+ ts <module 'timestring' from
'C:\mypath\Anaconda3\\lib\\site-packages\\timestring\\__init__.py'>
module

ipython traceback:

row[4]= ' "" '

Traceback (most recent call last):
  File "C:\mypath\visual studio
2015\Projects\Budget\Budget\Budget.py", line 28, in <module>
    expenses[ts.Date(row[0]).month] += decimal.Decimal(row[4])
decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]


I think the problem may be caused by an empty string value that is
passed to decimal.Decimal function. The csv file contains some empty
cells and I wanted the code to ignore them. That's why I had the
ValueError exception.



------------------------------------------


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

From alan.gauld at yahoo.co.uk  Sun May 22 11:44:54 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 22 May 2016 16:44:54 +0100
Subject: [Tutor] Python 3: string to decimal conversion
In-Reply-To: <CABYxsxvkRJ8haVJbnq63t=BwpCH+hvYiRYtzL6g2OzUwwzrwWw@mail.gmail.com>
References: <CA+SNFKwZdk3VxVu-q4qY+Cz=Hd0jMozEn5UDVZ3t+qS7G-B4OA@mail.gmail.com>
 <20160522033139.GA53172@cskk.homeip.net>
 <CABYxsxvkRJ8haVJbnq63t=BwpCH+hvYiRYtzL6g2OzUwwzrwWw@mail.gmail.com>
Message-ID: <nhsk5j$2bc$1@ger.gmane.org>

On 22/05/16 14:19, US wrote:

>>        with open(file) as csvfile:
>>            records = csv.reader(csvfile, quoting=csv.QUOTE_NONE)
> [...]
>>            for row in records:
> [...]
>>                try:
>>                    expenses[ts.Date(row[0]).month] +=
> decimal.Decimal(row[4])
>>                except ValueError:
>>                    pass

> I think the problem may be caused by an empty string value that is
> passed to decimal.Decimal function. The csv file contains some empty
> cells and I wanted the code to ignore them. That's why I had the
> ValueError exception.

If you know you are going to get some invalid data in your loop you
should test for it before the operation and use 'continue' to force the
loop to start the next iteration.  You could still catch the invalid
operation  error, just in case... Although, if you don't expect it and
don't know how to handle it then it's probably better to let Python just
do  its thing and give you the traceback.

Like this:

  with open(file) as csvfile:
     records = csv.reader(csvfile, quoting=csv.QUOTE_NONE)
       #...
       for row in records:
         if not row[4]:
             continue    # coz its empty
         else:
             expenses[ts.Date(row[0]).month] += decimal.Decimal(row[4])

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



From cs at zip.com.au  Sun May 22 18:36:29 2016
From: cs at zip.com.au (cs at zip.com.au)
Date: Mon, 23 May 2016 08:36:29 +1000
Subject: [Tutor] Python 3: string to decimal conversion
In-Reply-To: <CABYxsxvkRJ8haVJbnq63t=BwpCH+hvYiRYtzL6g2OzUwwzrwWw@mail.gmail.com>
References: <CABYxsxvkRJ8haVJbnq63t=BwpCH+hvYiRYtzL6g2OzUwwzrwWw@mail.gmail.com>
Message-ID: <20160522223629.GA12844@cskk.homeip.net>

On 22May2016 08:19, Saidov <usaidov at gmail.com> wrote:
>Thank you all for the useful feedback. I am new to programming so bear
>with me while I learn the rules...
>
>I have run Cameron's code to print the values and have the traceback
>results. please see below.
[...]
>>            for row in records:
>[...]
>>                try:
>>                    expenses[ts.Date(row[0]).month] +=
>decimal.Decimal(row[4])
>>                except ValueError:
>>                    pass
[...]
>I suggest that you print out the value of row[4] before the "try"
>statement:
>  print("row[4] =", repr(row[4]))
[...]
>+ decimal <module 'decimal' from 'C:\mypath\Anaconda3\\lib\\decimal.py'> 
>module
>+ expenses {1: Decimal('0'), 2: Decimal('0'), 3: Decimal('0'), 4:
>Decimal('0'), 5: Decimal('0'), 6: Decimal('0'), 7: Decimal('0'), 8:
>Decimal('0'), 9: Decimal('0'), 10: Decimal('0'), 11: Decimal('0'), 12:
>Decimal('0')} dict
>row[0] '"1/1/2016"' str
>row[4] '""' str
>+ ts <module 'timestring' from
>'C:\mypath\Anaconda3\\lib\\site-packages\\timestring\\__init__.py'>
>module
>
>ipython traceback:
>
>row[4]= ' "" '
>
>Traceback (most recent call last):
>  File "C:\mypath\visual studio
>2015\Projects\Budget\Budget\Budget.py", line 28, in <module>
>    expenses[ts.Date(row[0]).month] += decimal.Decimal(row[4])
>decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]
>
>I think the problem may be caused by an empty string value that is
>passed to decimal.Decimal function. The csv file contains some empty
>cells and I wanted the code to ignore them. That's why I had the
>ValueError exception.

I have two observations here:

Your strings in row[4] are not empty. If that output is repr(row[4]) then 
row[4] contains the text:

  ""

That is a two character string consisting of two quote characters.

Normally the csv.reader module will handle that for you, but I see that you 
passed the paramater:

  quoting=csv.QUOTE_NONE

to it when setting it up. It looks to me like your CSV file is a conventional 
one with quotes around string values. By passing csv.QUOTE_NONE you prevent the 
csv module from handling those for you and you get the "raw" column values. So 
a column with an empty string is probably written as "" in the file.

Could you show is the first line or so from your CSV file? That should tell us 
and you whether the file is "bare" comma separate values or the far more common 
quoted format.

If it is the quoted format, just remove the "quoting=csv.QUOTE_NONE" parameter 
altogether - the default for the csv module is quoted and it is _usually_ what 
is wanted. Of course you need to know one way or the other, so examine the CSV 
file itself.

The other observation is that you're trying to catch ValueError, when plainly 
the Decimal module is raising decimal.InvalidOperation. So you should catch 
that instead.

HOWEVER, just catching it and ignoring that row will _silently_ discard good 
input if you program is incorrect. You should almost always emit an error 
message or perform some other very specific action when you catch an exception.

Alan has suggested that you test specificly for an empty string.

I agree: you should act on exactly what is expected. By blindly catching 
ValueError or decimal.InvalidOperation and not reporting the string that caused 
it to happen you will silently ignore all kinds of unexpected input.

So I would advocate some code like this, similar to Alan's:

  if not row[4]:
    # empty column - we expect this and ignore it
    pass
  else:
    try:
      expenses[ts.Date(row[0]).month] += decimal.Decimal(row[4])
    except decimal.InvalidOperation as e:
      print("unexpected expenses value: %r" % (row[4],))

which will report the offending values, and presumably you expect either an 
empty column or a _valid_ expense value.

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

From palani at vahaitech.com  Mon May 23 03:54:21 2016
From: palani at vahaitech.com (Palanikumar Gopalakrishnan)
Date: Mon, 23 May 2016 13:24:21 +0530
Subject: [Tutor] which is best python 2 or python3
Message-ID: <CAN4mP=oC02LK4b6vvrUBrtc1WrxSwDHyuxVQ1AWnYnr=DPB6bQ@mail.gmail.com>

Hi buddies,
                    I read one article on internet which is said python 2
and python3 is totally different in programming.
As a beginner which i prefer for my learning,  python 2 or python3 ?

--

From usaidov at gmail.com  Sun May 22 21:45:17 2016
From: usaidov at gmail.com (US)
Date: Sun, 22 May 2016 20:45:17 -0500
Subject: [Tutor] Python 3: string to decimal conversion
In-Reply-To: <20160522223629.GA12844@cskk.homeip.net>
References: <CABYxsxvkRJ8haVJbnq63t=BwpCH+hvYiRYtzL6g2OzUwwzrwWw@mail.gmail.com>
 <20160522223629.GA12844@cskk.homeip.net>
Message-ID: <CABYxsxtXbScQvL7ynF=+r9P-8edgYVeP7ED_b_WHPCip-NB5Tg@mail.gmail.com>

On Sun, May 22, 2016 at 5:36 PM,  <cs at zip.com.au> wrote:
> On 22May2016 08:19, Saidov <usaidov at gmail.com> wrote:
>>
>> Thank you all for the useful feedback. I am new to programming so bear
>> with me while I learn the rules...
>>
>> I have run Cameron's code to print the values and have the traceback
>> results. please see below.
>
> [...]
>>>
>>>            for row in records:
>>
>> [...]
>>>
>>>                try:
>>>                    expenses[ts.Date(row[0]).month] +=
>>
>> decimal.Decimal(row[4])
>>>
>>>                except ValueError:
>>>                    pass
>
> [...]
>>
>> I suggest that you print out the value of row[4] before the "try"
>> statement:
>>  print("row[4] =", repr(row[4]))
>
> [...]
>>
>> + decimal <module 'decimal' from 'C:\mypath\Anaconda3\\lib\\decimal.py'>
>> module
>> + expenses {1: Decimal('0'), 2: Decimal('0'), 3: Decimal('0'), 4:
>> Decimal('0'), 5: Decimal('0'), 6: Decimal('0'), 7: Decimal('0'), 8:
>> Decimal('0'), 9: Decimal('0'), 10: Decimal('0'), 11: Decimal('0'), 12:
>> Decimal('0')} dict
>> row[0] '"1/1/2016"' str
>> row[4] '""' str
>> + ts <module 'timestring' from
>> 'C:\mypath\Anaconda3\\lib\\site-packages\\timestring\\__init__.py'>
>> module
>>
>> ipython traceback:
>>
>> row[4]= ' "" '
>>
>> Traceback (most recent call last):
>>  File "C:\mypath\visual studio
>> 2015\Projects\Budget\Budget\Budget.py", line 28, in <module>
>>    expenses[ts.Date(row[0]).month] += decimal.Decimal(row[4])
>> decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]
>>
>> I think the problem may be caused by an empty string value that is
>> passed to decimal.Decimal function. The csv file contains some empty
>> cells and I wanted the code to ignore them. That's why I had the
>> ValueError exception.
>
>
> I have two observations here:
>
> Your strings in row[4] are not empty. If that output is repr(row[4]) then
> row[4] contains the text:
>
>  ""
>
> That is a two character string consisting of two quote characters.
>
> Normally the csv.reader module will handle that for you, but I see that you
> passed the paramater:
>
>  quoting=csv.QUOTE_NONE
>
> to it when setting it up. It looks to me like your CSV file is a
> conventional one with quotes around string values. By passing csv.QUOTE_NONE
> you prevent the csv module from handling those for you and you get the "raw"
> column values. So a column with an empty string is probably written as "" in
> the file.
>
> Could you show is the first line or so from your CSV file? That should tell
> us and you whether the file is "bare" comma separate values or the far more
> common quoted format.
>
> If it is the quoted format, just remove the "quoting=csv.QUOTE_NONE"
> parameter altogether - the default for the csv module is quoted and it is
> _usually_ what is wanted. Of course you need to know one way or the other,
> so examine the CSV file itself.
>

Thanks, the csv.QUOTE_NONE was one of the parameters i changed
earlier. It didn't make any difference, unfortunately. I kept getting
the same error.

I visually inspected the csv file and the empty cells show up empty.
negative numbers are recorded as ($0.00), non-negative numbers as:
$0.00

Here are the first four lines:

Date No. Description Type Debit Credit
1/1/2016 income ex-2387280 CREDIT $303.65
1/3/2016 income ex-4732847 CREDIT $3.00
1/4/2016 insurance DEBIT ($75.59)

> The other observation is that you're trying to catch ValueError, when
> plainly the Decimal module is raising decimal. InvalidOperation. So you
> should catch that instead.
>
> HOWEVER, just catching it and ignoring that row will _silently_ discard good
> input if you program is incorrect. You should almost always emit an error
> message or perform some other very specific action when you catch an
> exception.
>
> Alan has suggested that you test specificly for an empty string.
>
> I agree: you should act on exactly what is expected. By blindly catching
> ValueError or decimal.InvalidOperation and not reporting the string that
> caused it to happen you will silently ignore all kinds of unexpected input.
>
> So I would advocate some code like this, similar to Alan's:
>
>  if not row[4]:
>    # empty column - we expect this and ignore it
>    pass
>  else:
>    try:
>      expenses[ts.Date(row[0]).month] += decimal.Decimal(row[4])
>    except decimal.InvalidOperation as e:
>      print("unexpected expenses value: %r" % (row[4],))
>
> which will report the offending values, and presumably you expect either an
> empty column or a _valid_ expense value.
>
> Cheers,
> Cameron Simpson <cs at zip.com.au>

Thank you both for suggesting a way to handle errors. I have run the
suggested code. What I learned is that all the values (not only empty
cells) seem to be invalid for decimal.Decimal function.

I tried the float() function instead of decimal.Decimal and got an
error message: could not convert string to float: '($75.59)'.

I also checked the type of values in row[4]. All the values passed on
to decimal.Decimal () function are indeed of string type...

Is there anything I can do to the formatting of the csv file to make
it 'readable' for decimal.Decimal function?

Here is my updated code along with the output I got from running it:

----------------------------------------------------
code:
import numpy as np
import csv
import timestring as ts
import decimal

months= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
expenses = {x: decimal.Decimal() for x in months}
income = {x: decimal.Decimal() for x in months}
test = []

exp_cat = []
income_cat = []

files =['export.csv']

with open("budgetfile.csv","wt") as fw:
    writer = csv.writer(fw)
    for file in files:
        with open(file, newline ='' ) as csvfile:
            records = csv.reader(csvfile)
            print("Processing file {}. \n" .format(file))
            header = next(records)
            for row in records:
                print("row[4] =", repr(row[4]), "value type =", type(row[4]))

                if not row[4]:
                    pass
                else:
                    try:
                        expenses[ts.Date(row[0]).month] +=
decimal.Decimal(row[4])
                    except decimal.InvalidOperation as e:
                        print("unexpected expenses value:  %r" % (row[4],))
----------------------------------------------------------------------------------------------------------------
last 4 lines of output:
[4] = '($10.00)' value type = <class 'str'>
unexpected expenses value:  '($10.00)'
row[4] = '($287.42)' value type = <class 'str'>
unexpected expenses value:  '($287.42)'
--------------------------------------------------------------------------------------------------------------

From alan.gauld at yahoo.co.uk  Mon May 23 05:39:17 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 23 May 2016 10:39:17 +0100
Subject: [Tutor] Python 3: string to decimal conversion
In-Reply-To: <CABYxsxtXbScQvL7ynF=+r9P-8edgYVeP7ED_b_WHPCip-NB5Tg@mail.gmail.com>
References: <CABYxsxvkRJ8haVJbnq63t=BwpCH+hvYiRYtzL6g2OzUwwzrwWw@mail.gmail.com>
 <20160522223629.GA12844@cskk.homeip.net>
 <CABYxsxtXbScQvL7ynF=+r9P-8edgYVeP7ED_b_WHPCip-NB5Tg@mail.gmail.com>
Message-ID: <nhuj42$a4v$1@ger.gmane.org>

On 23/05/16 02:45, US wrote:

> I tried the float() function instead of decimal.Decimal and got an
> error message: could not convert string to float: '($75.59)'.

The problem is that the functions don;t recognize the parens as a
negative sign. You will need to convert them yourself. I suggest you
write a function that takes a string and if it starts with parens then
strip them off and prepend a negative sign, otherwise return the
original. You will also need to get rid of the $ sign...
Something like:

def normalizeValue(val):
    if amt.startswith('(') and amt.endswith(')'):
       amt = '-' + amt[1:-1]
    return amt.replace('$','')

Then call that when you try to convert to Decimal


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



From alan.gauld at yahoo.co.uk  Mon May 23 05:41:30 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 23 May 2016 10:41:30 +0100
Subject: [Tutor] which is best python 2 or python3
In-Reply-To: <CAN4mP=oC02LK4b6vvrUBrtc1WrxSwDHyuxVQ1AWnYnr=DPB6bQ@mail.gmail.com>
References: <CAN4mP=oC02LK4b6vvrUBrtc1WrxSwDHyuxVQ1AWnYnr=DPB6bQ@mail.gmail.com>
Message-ID: <nhuj88$a4v$2@ger.gmane.org>

On 23/05/16 08:54, Palanikumar Gopalakrishnan wrote:
> Hi buddies,
>                     I read one article on internet which is said python 2
> and python3 is totally different in programming.
> As a beginner which i prefer for my learning,  python 2 or python3 ?

Nowadays the only real justifications for a learner using Python2
are: 1) It's all they can access on their computer or 2) they know
they need a library that is only available on 2.

Otherwise it makes more sense to learn Python 3

Just make sure the tutorial you follow is also Python 3!

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



From __peter__ at web.de  Mon May 23 06:06:51 2016
From: __peter__ at web.de (Peter Otten)
Date: Mon, 23 May 2016 12:06:51 +0200
Subject: [Tutor] Python 3: string to decimal conversion
References: <CABYxsxvkRJ8haVJbnq63t=BwpCH+hvYiRYtzL6g2OzUwwzrwWw@mail.gmail.com>
 <20160522223629.GA12844@cskk.homeip.net>
 <CABYxsxtXbScQvL7ynF=+r9P-8edgYVeP7ED_b_WHPCip-NB5Tg@mail.gmail.com>
Message-ID: <nhuknt$32e$1@ger.gmane.org>

US wrote:

> Thank you both for suggesting a way to handle errors. I have run the
> suggested code. What I learned is that all the values (not only empty
> cells) seem to be invalid for decimal.Decimal function.
> 
> I tried the float() function instead of decimal.Decimal and got an
> error message: could not convert string to float: '($75.59)'.
> 
> I also checked the type of values in row[4]. All the values passed on
> to decimal.Decimal () function are indeed of string type...
> 
> Is there anything I can do to the formatting of the csv file to make
> it 'readable' for decimal.Decimal function?
> 
> Here is my updated code along with the output I got from running it:
> 
> ----------------------------------------------------
> code:
> import numpy as np
> import csv
> import timestring as ts
> import decimal
> 
> months= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
> expenses = {x: decimal.Decimal() for x in months}
> income = {x: decimal.Decimal() for x in months}
> test = []
> 
> exp_cat = []
> income_cat = []
> 
> files =['export.csv']
> 
> with open("budgetfile.csv","wt") as fw:
>     writer = csv.writer(fw)
>     for file in files:
>         with open(file, newline ='' ) as csvfile:
>             records = csv.reader(csvfile)
>             print("Processing file {}. \n" .format(file))
>             header = next(records)
>             for row in records:
>                 print("row[4] =", repr(row[4]), "value type =",
>                 type(row[4]))
> 
>                 if not row[4]:
>                     pass
>                 else:
>                     try:
>                         expenses[ts.Date(row[0]).month] +=
> decimal.Decimal(row[4])
>                     except decimal.InvalidOperation as e:
>                         print("unexpected expenses value:  %r" %
>                         (row[4],))

> last 4 lines of output:
> [4] = '($10.00)' value type = <class 'str'>
> unexpected expenses value:  '($10.00)'
> row[4] = '($287.42)' value type = <class 'str'>
> unexpected expenses value:  '($287.42)'

Perhaps you should use a custom conversion routine like to_decimal() below:

class MissingValue(ValueError):
    pass


@contextlib.contextmanager
def expect(exc):
    """Ensure that an excption of type `exc` was raised.

    Helper for the doctests.
    """
    try:
        yield
    except exc:
        pass
    except:
        raise AssertionError(
            "Wrong exception type (expected {})".format(exc))
    else:
        raise AssertionError("Exception was not raised")


def to_decimal(s):
    """
    >>> with expect(MissingValue):
    ...     to_decimal("   ")
    >>> with expect(ValueError):
    ...     to_decimal("42")
    >>> to_decimal("$12.34")
    Decimal('12.34')
    >>> to_decimal("($34.56)")
    Decimal('-34.56')
    >>> with expect(ValueError):
    ...     to_decimal("foo")
    >>> with expect(ValueError):
    ...     to_decimal("$bar")
    >>> with expect(ValueError):
    ...     to_decimal("($baz)")
    """
    s = s.strip()  # remove leading/trailing whitespace
    if not s:
        raise MissingValue("Empty amount")
    if s.startswith("(") and s.endswith(")"):
        sign = -1
        s = s[1:-1]  # remove parens
    else:
        sign = 1
    if not s.startswith("$"):
        raise ValueError("No leading $ found")
    s = s[1:]  # remove $
    try:
        value = decimal.Decimal(s)
    except decimal.InvalidOperation as err:
        raise ValueError(err.args[0]) from None
    return sign * value


That way you can spell out explicitly what the allowed values may look like, 
and if (e. g.) you want to allow for grouping you can easily add another 
preprocessing step to remove the commas. Use it like so in your code:

...
for row in records:
    try:
        amount = to_decimal(row[4])
    except ValueError as err:
        print(err, file=sys.stderr)
    else:
        ...  # add amount to expenses
...


From steve at pearwood.info  Mon May 23 08:34:36 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 23 May 2016 22:34:36 +1000
Subject: [Tutor] which is best python 2 or python3
In-Reply-To: <CAN4mP=oC02LK4b6vvrUBrtc1WrxSwDHyuxVQ1AWnYnr=DPB6bQ@mail.gmail.com>
References: <CAN4mP=oC02LK4b6vvrUBrtc1WrxSwDHyuxVQ1AWnYnr=DPB6bQ@mail.gmail.com>
Message-ID: <20160523123435.GT12028@ando.pearwood.info>

On Mon, May 23, 2016 at 01:24:21PM +0530, Palanikumar Gopalakrishnan wrote:
> Hi buddies,
>                     I read one article on internet which is said python 2
> and python3 is totally different in programming.
> As a beginner which i prefer for my learning,  python 2 or python3 ?

They are not total different. They are very similar: like British and 
American English. Most things are the same, a few things are slightly 
different.

As a beginner, you should choose a tutorial, and use whatever version of 
Python the tutorial uses.

But if you have a choice, Python 3 is more modern, and has more 
features, and has fixed some problems with Python 2. You should use 
Python 3 for new projects.


-- 
Steve

From usaidov at gmail.com  Mon May 23 13:18:58 2016
From: usaidov at gmail.com (US)
Date: Mon, 23 May 2016 12:18:58 -0500
Subject: [Tutor] Python 3: string to decimal conversion
In-Reply-To: <nhuknt$32e$1@ger.gmane.org>
References: <CABYxsxvkRJ8haVJbnq63t=BwpCH+hvYiRYtzL6g2OzUwwzrwWw@mail.gmail.com>
 <20160522223629.GA12844@cskk.homeip.net>
 <CABYxsxtXbScQvL7ynF=+r9P-8edgYVeP7ED_b_WHPCip-NB5Tg@mail.gmail.com>
 <nhuknt$32e$1@ger.gmane.org>
Message-ID: <CABYxsxu9TwCwiwYrqYAM+tA5SrkEs7xqv4peaxrwNZghs9La3g@mail.gmail.com>

Thanks everyone for all your help. This solved my problem with
parenthesis and $ signs in the data:

if not row[4]:
                    pass
                else:
                    try:
                        expenses[ts.Date(row[0]).month] +=
decimal.Decimal(row[4].strip('()$ ,').replace(',',''))
                    except decimal.InvalidOperation as e:
                        print("unexpected expenses value:  %r" % (row[4]))

On Mon, May 23, 2016 at 5:06 AM, Peter Otten <__peter__ at web.de> wrote:
> US wrote:
>
>> Thank you both for suggesting a way to handle errors. I have run the
>> suggested code. What I learned is that all the values (not only empty
>> cells) seem to be invalid for decimal.Decimal function.
>>
>> I tried the float() function instead of decimal.Decimal and got an
>> error message: could not convert string to float: '($75.59)'.
>>
>> I also checked the type of values in row[4]. All the values passed on
>> to decimal.Decimal () function are indeed of string type...
>>
>> Is there anything I can do to the formatting of the csv file to make
>> it 'readable' for decimal.Decimal function?
>>
>> Here is my updated code along with the output I got from running it:
>>
>> ----------------------------------------------------
>> code:
>> import numpy as np
>> import csv
>> import timestring as ts
>> import decimal
>>
>> months= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>> expenses = {x: decimal.Decimal() for x in months}
>> income = {x: decimal.Decimal() for x in months}
>> test = []
>>
>> exp_cat = []
>> income_cat = []
>>
>> files =['export.csv']
>>
>> with open("budgetfile.csv","wt") as fw:
>>     writer = csv.writer(fw)
>>     for file in files:
>>         with open(file, newline ='' ) as csvfile:
>>             records = csv.reader(csvfile)
>>             print("Processing file {}. \n" .format(file))
>>             header = next(records)
>>             for row in records:
>>                 print("row[4] =", repr(row[4]), "value type =",
>>                 type(row[4]))
>>
>>                 if not row[4]:
>>                     pass
>>                 else:
>>                     try:
>>                         expenses[ts.Date(row[0]).month] +=
>> decimal.Decimal(row[4])
>>                     except decimal.InvalidOperation as e:
>>                         print("unexpected expenses value:  %r" %
>>                         (row[4],))
>
>> last 4 lines of output:
>> [4] = '($10.00)' value type = <class 'str'>
>> unexpected expenses value:  '($10.00)'
>> row[4] = '($287.42)' value type = <class 'str'>
>> unexpected expenses value:  '($287.42)'
>
> Perhaps you should use a custom conversion routine like to_decimal() below:
>
> class MissingValue(ValueError):
>     pass
>
>
> @contextlib.contextmanager
> def expect(exc):
>     """Ensure that an excption of type `exc` was raised.
>
>     Helper for the doctests.
>     """
>     try:
>         yield
>     except exc:
>         pass
>     except:
>         raise AssertionError(
>             "Wrong exception type (expected {})".format(exc))
>     else:
>         raise AssertionError("Exception was not raised")
>
>
> def to_decimal(s):
>     """
>     >>> with expect(MissingValue):
>     ...     to_decimal("   ")
>     >>> with expect(ValueError):
>     ...     to_decimal("42")
>     >>> to_decimal("$12.34")
>     Decimal('12.34')
>     >>> to_decimal("($34.56)")
>     Decimal('-34.56')
>     >>> with expect(ValueError):
>     ...     to_decimal("foo")
>     >>> with expect(ValueError):
>     ...     to_decimal("$bar")
>     >>> with expect(ValueError):
>     ...     to_decimal("($baz)")
>     """
>     s = s.strip()  # remove leading/trailing whitespace
>     if not s:
>         raise MissingValue("Empty amount")
>     if s.startswith("(") and s.endswith(")"):
>         sign = -1
>         s = s[1:-1]  # remove parens
>     else:
>         sign = 1
>     if not s.startswith("$"):
>         raise ValueError("No leading $ found")
>     s = s[1:]  # remove $
>     try:
>         value = decimal.Decimal(s)
>     except decimal.InvalidOperation as err:
>         raise ValueError(err.args[0]) from None
>     return sign * value
>
>
> That way you can spell out explicitly what the allowed values may look like,
> and if (e. g.) you want to allow for grouping you can easily add another
> preprocessing step to remove the commas. Use it like so in your code:
>
> ...
> for row in records:
>     try:
>         amount = to_decimal(row[4])
>     except ValueError as err:
>         print(err, file=sys.stderr)
>     else:
>         ...  # add amount to expenses
> ...
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

From cs at zip.com.au  Mon May 23 21:50:03 2016
From: cs at zip.com.au (cs at zip.com.au)
Date: Tue, 24 May 2016 11:50:03 +1000
Subject: [Tutor] Python 3: string to decimal conversion
In-Reply-To: <CABYxsxu9TwCwiwYrqYAM+tA5SrkEs7xqv4peaxrwNZghs9La3g@mail.gmail.com>
References: <CABYxsxu9TwCwiwYrqYAM+tA5SrkEs7xqv4peaxrwNZghs9La3g@mail.gmail.com>
Message-ID: <20160524015003.GA44454@cskk.homeip.net>

On 23May2016 12:18, Saidov <usaidov at gmail.com> wrote:
>Thanks everyone for all your help. This solved my problem with
>parenthesis and $ signs in the data:
>
>if not row[4]:
>                    pass
>                else:
>                    try:
>                        expenses[ts.Date(row[0]).month] +=
>decimal.Decimal(row[4].strip('()$ ,').replace(',',''))
>                    except decimal.InvalidOperation as e:
>                        print("unexpected expenses value:  %r" % (row[4]))

These are three things to remark on with your new code:

Firstly, it is best to put try/except around as narrow a piece of code as 
possible. In your code about, you would catch decimal.InvalidOperation from any 
of the operations, including the strip and .replace operations. While it 
happens that these do not raise that exception, the problem is that when an 
exception is raised you have a much vaguer idea of where it came from, 
especially with more common exceptions like ValueError.

Therefore I would suggest reshaping the above like this:

    numeric_expense = row[4].strip('()$ ,').replace(',', '')
    try:
        expense = decimal.Decimal(numeric_expense)
    except decimal.InvalidOperation as e:
        print("unexpected numeric expsense: %r (%s)" % (numeric_expense, e))
    else:
        expenses[ts.Date(row[0]).month] += expense

In this way you are watching for _only_ the decimal.Decimal() call, not the 
other methods. Also, it makes it easy to report the actual string that caused 
the trouble (numeric_expense) because you have now pulled it out and given it a 
nice name. This means that your note reporting an error about row[4] _before_ 
it got cleaned up, you're reporting about how it was after the cleanup. Also, 
we're printing the exception itself in the message as well as the string: here 
it may not help more, but with many exceptions there will be further detail 
which can be helpful, so it is good practice to print the exception (e).

Second, error messages should go to the program's error output, which is a 
separate output stream from stdout. So the print should look like this:

    print(....., file=sys.stderr)

When it is all going to your terminal you won't see the f=difference, but as 
soon as your program is run like this:

    python my-program.py >report.txt

you will get the "report" information in your file and the error output will 
still show up on your terminal where you will see it.

Thirdly, your .strip('()') is throwing away the brackets around the expense. As 
Alan pointed out, it is common convention in accounting to express negaitve 
values (losses, withdrawals, etc) in brakcets. So this "4.00" means 4.00 and 
this "(4.00)" means -4.00. And in consequence you should probably be 
_subtracting_ any value in brackets instead of adding it. This is why ALan had 
a distinct if-statement to recognise the brackets. Example, untested:

    if row[4].startswith('(') and row[4].endswith(')'):
        row[4] = row[4][1:-1]
        negative = True
    else:
        negative = False
    # ... string $ sign and commas, convert to Decimal ...
    try:  ....
    except ....:
    else:
        if negative:
            expense = -expense
        expenses[ts.Date(row[0]).month] += expense

As your code current is, it is adding all the negative values, which may not be 
what is needed.

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

From crusier at gmail.com  Mon May 23 23:17:54 2016
From: crusier at gmail.com (Crusier)
Date: Tue, 24 May 2016 11:17:54 +0800
Subject: [Tutor] Web Page Scraping
Message-ID: <CAC7HCj9y0t+=hNOzG6rJv=nsXydABA6kHFzYe2XP+y7Asa=oTQ@mail.gmail.com>

Dear All,

I am trying to scrape a web site using Beautiful Soup. However, BS
doesn't show any of the data. I am just wondering if it is Javascript
or some other feature which hides all the data.

I have the following questions:

1) Please advise how to scrape the following data from the website:

'http://www.dbpower.com.hk/en/quote/quote-warrant/code/10348'

Type, Listing Date (Y-M-D), Call / Put, Last Trading Day (Y-M-D),
Strike Price, Maturity Date (Y-M-D),  Effective Gearing (X),Time to
Maturity (D),
Delta (%), Daily Theta (%),  Board Lot.......

2) I am able to scrape most of the data from the same site

'http://www.dbpower.com.hk/en/quote/quote-cbbc/code/63852'

 Please advise what is the difference between these two sites.
Attached is my code

Thank you

Regards,
Hank

from bs4 import BeautifulSoup
import requests
import json
import re

warrants = ['10348']

def web_scraper(warrants):

    url = "http://www.dbpower.com.hk/en/quote/quote-warrant/code/"

    # Scrape from the Web
    for code in warrants:
        new_url = url + code
        response = requests.get(new_url)
        html = response.content
        soup = BeautifulSoup(html,"html.parser")
        print(soup)


        name = soup.findAll('div', attrs={'class': 'article_content'})
        #print(name)

        for n in name:
            name1 = str(n.text)
            s_code = name1[:4]
            print(name1)


web_scraper(warrants)

From __peter__ at web.de  Tue May 24 03:59:48 2016
From: __peter__ at web.de (Peter Otten)
Date: Tue, 24 May 2016 09:59:48 +0200
Subject: [Tutor] Python 3: string to decimal conversion
References: <CABYxsxu9TwCwiwYrqYAM+tA5SrkEs7xqv4peaxrwNZghs9La3g@mail.gmail.com>
 <20160524015003.GA44454@cskk.homeip.net>
Message-ID: <ni11lk$fm2$1@ger.gmane.org>

cs at zip.com.au wrote:

> On 23May2016 12:18, Saidov <usaidov at gmail.com> wrote:
>>Thanks everyone for all your help. This solved my problem with
>>parenthesis and $ signs in the data:
>>
>>if not row[4]:
>>                    pass
>>                else:
>>                    try:
>>                        expenses[ts.Date(row[0]).month] +=
>>decimal.Decimal(row[4].strip('()$ ,').replace(',',''))
>>                    except decimal.InvalidOperation as e:
>>                        print("unexpected expenses value:  %r" % (row[4]))
> 
> These are three things to remark on with your new code:

Noughtily?

Whatever you do, the conversion is complex enough to put it into a separate 
function. This makes it easier to test the code against typical input and 
corner cases.

> Firstly, it is best to put try/except around as narrow a piece of code as 

[...] 



From carroll at tjc.com  Mon May 23 19:26:42 2016
From: carroll at tjc.com (Terry Carroll)
Date: Mon, 23 May 2016 16:26:42 -0700 (PDT)
Subject: [Tutor] Getting started in testing
In-Reply-To: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>
References: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>
Message-ID: <alpine.LRH.2.00.1605231624290.31398@aqua.rahul.net>

Thanks to Alan, Danny, Albert-Jan and Ben for their suggestions. I've now 
gotten my feet wet in unittest and have gone from not quite knowing 
where to start to making substantial progress, with a small suite of tests 
up and running.

From terry.kemmerer at gmail.com  Mon May 23 18:08:45 2016
From: terry.kemmerer at gmail.com (Terry--gmail)
Date: Mon, 23 May 2016 16:08:45 -0600
Subject: [Tutor] Learning Regular Expressions
Message-ID: <57437F6D.9010808@gmail.com>

Running Linux Mint
The YouTube Sentdex Video tutor I am following.
He is working in Python3.4 and I am running Python3.4.3

He's demonstrating some Regular Expressions which I wanted to test out. 
On these test scripts, for future referrence, I have been putting my 
notes in Tripple Quotes and naming the scripts descriptively to be able 
to find them again, when I need to review. However, this time, when  I 
copied in a simple script below my RE notes, and ran it from IDLE (and 
from Console) I got the following error:

SyntaxError:  EOF while scanning triple-quoted string literal

Now, there was also a tripple-quoted string I had set a variable to in 
my script...so I thought it was the active part of the script! But 
eventually, through the process of elimination, I discovered the 
scripted worked great without the notes!  I'd like to know what it is in 
the below Tripple-Quoted section that is causing me this problem...if 
anyone recognizes. In IDLE's script file..._it's all colored green_, 
which I thought meant Python was going to ignore everything between the 
tripple-quotes! But if I run just the below portion of the script in 
it's own file, I get the same While Scanning Tripple-Quotes error.

#!/usr/bin/env python3

'''
Regular Expressions - or at least some

Identifiers:

\d  any number
\D  anything but a number (digit)
\s  space
\S  anything but a space
\w  any character
\W  anything but a character
.   any character (or even a period itself if you use \.) except for a 
newline
a   search for just the letter 'a'
\b  the white space around words

Modifiers
{x}    we are expecting "x" number of something
{1, 3}  we're expecting 1-3 in length of something -, so for digits we 
write  \d{1-3}
+  means Match 1 or more
?  means Match 0 or 1
*   Match 0 or more
$  Match the end of a string
^  Match the beginning of a string
|   Match either or   - so you might write  \d{1-3} | \w{5-6}
[ ]  a range or "variance" such as [A-Z] or [A-Za-z] Cap 1st letter 
followed by lower case
             or [1-5a-qA-Z] starts with a number inclusive of 1-5 then 
lower case letter then
             followed by any Cap letter! :)

White Space Characters  (may not be seen):
\n  new line
\s  space
\t   tab
\e  escape
\f  form feed
\r  return

DON'T FORGET!:
.  +  *  ?  [  ]  $  ^  (  )  {  }  |  \   if you really want to use 
these, you must escape them '\'

'''

Thanks for your thoughts!
--Terry

From wprins at gmail.com  Tue May 24 10:37:08 2016
From: wprins at gmail.com (Walter Prins)
Date: Tue, 24 May 2016 15:37:08 +0100
Subject: [Tutor] Web Page Scraping
In-Reply-To: <CAC7HCj9y0t+=hNOzG6rJv=nsXydABA6kHFzYe2XP+y7Asa=oTQ@mail.gmail.com>
References: <CAC7HCj9y0t+=hNOzG6rJv=nsXydABA6kHFzYe2XP+y7Asa=oTQ@mail.gmail.com>
Message-ID: <CANLXbfC==2rJs5hXWymbUK6Tx+mMk9jwkem7amTxrq5M7sBx2g@mail.gmail.com>

Hi,


On 24 May 2016 at 04:17, Crusier <crusier at gmail.com> wrote:
>
> Dear All,
>
> I am trying to scrape a web site using Beautiful Soup. However, BS
> doesn't show any of the data. I am just wondering if it is Javascript
> or some other feature which hides all the data.
>
> I have the following questions:
>
> 1) Please advise how to scrape the following data from the website:
>
> 'http://www.dbpower.com.hk/en/quote/quote-warrant/code/10348'
>
> Type, Listing Date (Y-M-D), Call / Put, Last Trading Day (Y-M-D),
> Strike Price, Maturity Date (Y-M-D),  Effective Gearing (X),Time to
> Maturity (D),
> Delta (%), Daily Theta (%),  Board Lot.......
>
> 2) I am able to scrape most of the data from the same site
>
> 'http://www.dbpower.com.hk/en/quote/quote-cbbc/code/63852'
>
>  Please advise what is the difference between these two sites.


You didn't state which version of Python you're using, nor what
operating system, but the source contains print's with parenthesis, so
I assume some version of Python 3 and I'm going to guess you're using
Windows.  Be that as it may, your program crashes with both Python 2
and Python 3.  The str() conversion is flagged as a problem by
Python2, stating:

"Traceback (most recent call last):
  File "test.py", line 30, in <module>
    web_scraper(warrants)
  File "test.py", line 25, in web_scraper
    name1 = str(n.text)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in
position 282: ordinal not in range(128)"

Meanwhile Python3 breaks earlier with the message:

"Traceback (most recent call last):
  File "test.py", line 30, in <module>
    web_scraper(warrants)
  File "test.py", line 18, in web_scraper
    print(soup)
  File "C:\Python35-32\lib\encodings\cp850.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in
position 435-439: character maps to <undefined>"

Both of these alert you to the fact that this is due to some encoding
issue.  Aside from this your program seems to work, and the data you
say you want to retrieve is in fact returned.

So in short: If you avoid trying to implicitly encode the Unicode
result from Beautiful soup into ASCII (or the local machine codepage)
implicitly (which is what happens with your unqualified print calls)
you should avoid the problem.

But I guess you're going to want to continue to use print, and you may
therefore want to know what the issue is and how you might avoid it.

So: The reason for the problem is (basically as I understand it) that
on Windows your console (which is where the results of the print
statements go) is not Unicode aware.  This implies that when you ask
Python to print a Unicode string to the console, that first of all
there must be a conversion from Unicode to something your console can
accept, to allow the print to execute.  On Python 2 if you don't
explicitly deal with this, "ascii" is used which then duly falls over
if it runs into anything that doesn't map cleanly into the ASCII
character set.  On Python 3, it is clever enough to figure out what my
console codepage (cp850) is, which means more characters are mappable
to my console character set, however this is still not enough to
convert character 435-439 which is encountered in the Beautifulsoup
result, as mentioned in the error message.

The way to avoid this is to tell Python how to deal with this. For
example (change lines marked with ****):

from bs4 import BeautifulSoup
import requests
import json
import re
import sys #****

warrants = ['10348']

def web_scraper(warrants):

    url = "http://www.dbpower.com.hk/en/quote/quote-warrant/code/"

    # Scrape from the Web
    for code in warrants:
        new_url = url + code
        response = requests.get(new_url)
        html = response.content
        soup = BeautifulSoup(html,"html.parser")
        print(soup.encode(sys.stdout.encoding, "backslashreplace")) #****


        name = soup.findAll('div', attrs={'class': 'article_content'})
        #print(name)

        for n in name:
            name1 = n.text   #****
            s_code = name1[:4]
            print(name1.encode(sys.stdout.encoding, "backslashreplace")) #****


web_scraper(warrants)


Here I'm picking up the encoding from stdout, which on my machine =
"cp850".  If sys.stdout.encoding is blank on your machine you might
try something explicit or as a last resort you might try "utf-8" that
should at least make the text "printable" (though perhaps not what you
want.)

I hope that helps (and look forward to possible corrections or
improved advice from other list members as I'm admittedly not an
expert on Unicode handling either.)

For reference, in future always post full error messages, and version
of Python/Operating system.

Cheers

Walter

From wprins at gmail.com  Tue May 24 10:45:12 2016
From: wprins at gmail.com (Walter Prins)
Date: Tue, 24 May 2016 15:45:12 +0100
Subject: [Tutor] Web Page Scraping
In-Reply-To: <CANLXbfC==2rJs5hXWymbUK6Tx+mMk9jwkem7amTxrq5M7sBx2g@mail.gmail.com>
References: <CAC7HCj9y0t+=hNOzG6rJv=nsXydABA6kHFzYe2XP+y7Asa=oTQ@mail.gmail.com>
 <CANLXbfC==2rJs5hXWymbUK6Tx+mMk9jwkem7amTxrq5M7sBx2g@mail.gmail.com>
Message-ID: <CANLXbfDtHWxDoOZShgxZ-76g+hRkW9Bm9ZXg7mEv1JcXak=1kQ@mail.gmail.com>

On 24 May 2016 at 15:37, Walter Prins <wprins at gmail.com> wrote:
>             print(name1.encode(sys.stdout.encoding, "backslashreplace")) #****

I forgot to mention, you might want to read the following documentation page:

https://docs.python.org/3/howto/unicode.html

(good luck.....)

W

From robertvstepp at gmail.com  Tue May 24 10:46:13 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Tue, 24 May 2016 09:46:13 -0500
Subject: [Tutor] Learning Regular Expressions
In-Reply-To: <57437F6D.9010808@gmail.com>
References: <57437F6D.9010808@gmail.com>
Message-ID: <CANDiX9Ky71MCtRKmFP_yXnaU+WP=pq5cV3vAKABa8fhpjjqB=A@mail.gmail.com>

On Mon, May 23, 2016 at 5:08 PM, Terry--gmail <terry.kemmerer at gmail.com> wrote:
> Running Linux Mint
> The YouTube Sentdex Video tutor I am following.
> He is working in Python3.4 and I am running Python3.4.3
>
> He's demonstrating some Regular Expressions which I wanted to test out. On
> these test scripts, for future referrence, I have been putting my notes in
> Tripple Quotes and naming the scripts descriptively to be able to find them
> again, when I need to review. However, this time, when  I copied in a simple
> script below my RE notes, and ran it from IDLE (and from Console) I got the
> following error:
>
> SyntaxError:  EOF while scanning triple-quoted string literal
>
> Now, there was also a tripple-quoted string I had set a variable to in my
> script...so I thought it was the active part of the script! But eventually,
> through the process of elimination, I discovered the scripted worked great
> without the notes!  I'd like to know what it is in the below Tripple-Quoted
> section that is causing me this problem...if anyone recognizes. In IDLE's
> script file..._it's all colored green_, which I thought meant Python was
> going to ignore everything between the tripple-quotes! But if I run just the
> below portion of the script in it's own file, I get the same While Scanning
> Tripple-Quotes error.

I do not know the exact point of error in your code, but even if you
use triple-quoted strings, escape sequences still work.  I do not have
a Python 3 installation handy, but in the Python 2.7.8 that I do have
handy:

Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit
(Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> print '''
\tTab character!!!
'''

        Tab character!!!

>>>

Note:  I had to simulate with spaces what I see in IDLE as my Gmail
refuses to accurately copy my IDLE result.

I suspect that your multiple backslash instances are generating what
you are observing.  Doesn't your full traceback target the exact line
of your code on which this occurs?

HTH,
boB

From imcclear2u at yahoo.com  Tue May 24 13:06:09 2016
From: imcclear2u at yahoo.com (Angelia Spencer)
Date: Tue, 24 May 2016 17:06:09 +0000 (UTC)
Subject: [Tutor] I've subscribed to your service,
 no confirmation yet. I'm looking for a tutor and I need help with
 some code.
References: <1884075547.1942590.1464109569987.JavaMail.yahoo.ref@mail.yahoo.com>
Message-ID: <1884075547.1942590.1464109569987.JavaMail.yahoo@mail.yahoo.com>

?I'm trying to telnet to my box. When I do this in DOS it's simple, I even have a blinking cursor for me to type in commands for each response. Not so for python. I have a dictionary "user_acct" which has the username and password in it. My box is interactive, I must be able to type in commands and I don't know how to do this in python. Pleasehelp me any way you can.
1st prompt = Username:2nd prompt = Password:

After this my box's output looks like this:Last Login Date????? : May 24 2016 09:42:08
Last Login Type????? : IP Session(CLI)
Login Failures?????? : 0 (Since Last Login)
???????????????????? : 0 (Total for Account)
TA5000>then I type en and get
TA5000# then I type conf t and getTA5000(config)#
My code is below:

import getpass
import sys
import telnetlibusername = input()
password = input()
tid = 'TA5000'
first_prompt = '>' # type 'en' at this prompt
second_prompt = '#' # type 'conf t' at this prompt
third_prompt = '(config)'
prompt1 = tid + first_prompt
prompt2 = tid + second_prompt
prompt3 = tid + third_prompt + second_prompt
user_acct = {'ADMIN':'PASSWORD','ADTRAN':'BOSCO','READONLY':'PASSWORD','READWRITE':'PASSWORD','TEST':'PASSWORD','guest':'PASSWORD','':'PASSWORD'}
host = "10.51.18.88"
#username = "ADMIN" + newline
#password = "PASSWORD" + newline
tn = telnetlib.Telnet(host,"23")
open()
tn.read_until("Username: ")
tn.write(username)
tn.read_until("Password: ")
tn.write(password)if username in user_acct and password == user_acct[username]: 
???? print(prompt1 + "Enter en at this prompt" +"\n")
???? print(prompt2 + "Enter conf t at this prompt" + "\n")
???? print(prompt3 + "\n")
else:
???? 
???? print('Invalid Login... Please Try Again')close()



...you cannot direct the wind but you can adjust your sails...??Angelia Spencer (Angie)

From alan.gauld at yahoo.co.uk  Tue May 24 15:38:22 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 24 May 2016 20:38:22 +0100
Subject: [Tutor] I've subscribed to your service,
 no confirmation yet. I'm looking for a tutor and I need help with
 some code.
In-Reply-To: <1884075547.1942590.1464109569987.JavaMail.yahoo@mail.yahoo.com>
References: <1884075547.1942590.1464109569987.JavaMail.yahoo.ref@mail.yahoo.com>
 <1884075547.1942590.1464109569987.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <ni2ajc$bh$1@ger.gmane.org>

Re your subject...
This is a mailing list. You subscribe and you should receive
mails sent to the list.
If you have a question send it to the list (like you did here)
and one or more of the list members will hopefully respond.
The more specific your question the more precise will be the response.
Try to include OS, Python version, any error messages(in full)

Now to your message...

On 24/05/16 18:06, Angelia Spencer via Tutor wrote:
>  I'm trying to telnet to my box. 

What is your "box"? A server somewhere? Running what OS?
Where are you telnetting from?

> When I do this in DOS it's simple, I even have a blinking cursor 
> for me to type in commands for each response.

I assume you mean you telnet from a Windows PC and login to your server
and get an OS command prompt? (Possibly running bash?)

> Not so for python. 

What does this mean? If you run the python command on your DOS
console you should get a prompt like

>>>

at which you can type in commands.

If python is installed on your "box" then telnet to the box
and at the OS prompt type python.

If that doesn't work for you, you will need to give us a lot more
information about how you installed Python, which version, how
you are trying to run python etc.

> I have a dictionary "user_acct" which has the username
> and password in it. 

> My box is interactive, I must be able to type in commands 

Again we have no idea what your "box" is. What do you mean
its interactive, nearly all computers are to some extent?

> and I don't know how to do this in python.

While python does have an interactive mode (the >>> prompt) it's not
normally used that way. Usually you put your code in a script file
(ending .py) and run it from an OS prompt (or file manager) like

C:\WINDOWS> python myscript.py

> 1st prompt = Username:2nd prompt = Password:
> 
> After this my box's output looks like this:Last Login Date      : May 24 2016 09:42:08
> Last Login Type      : IP Session(CLI)
> Login Failures       : 0 (Since Last Login)
>                      : 0 (Total for Account)
> TA5000>then I type en and get
> TA5000# then I type conf t and getTA5000(config)#

OK, I'm guessing that's a Unix like system but I'm not sure.

> My code is below:

How are you trying to run this?
Where is it stored?
Where is python installed?

> import getpass
> import sys
> import telnetlib

username = input()

> password = input()
> tid = 'TA5000'
> first_prompt = '>' # type 'en' at this prompt
> second_prompt = '#' # type 'conf t' at this prompt
> third_prompt = '(config)'
> prompt1 = tid + first_prompt
> prompt2 = tid + second_prompt
> prompt3 = tid + third_prompt + second_prompt
> user_acct = {'ADMIN':'PASSWORD','ADTRAN':'BOSCO','READONLY':'PASSWORD','READWRITE':'PASSWORD','TEST':'PASSWORD','guest':'PASSWORD','':'PASSWORD'}
> host = "10.51.18.88"
> #username = "ADMIN" + newline
> #password = "PASSWORD" + newline
> tn = telnetlib.Telnet(host,"23")
> open()

That calls the builtin open() function without arguments which should
cause an error. Do you get an error message?

You probably wanted

tn.open()

> tn.read_until("Username: ")
> tn.write(username)
> tn.read_until("Password: ")
> tn.write(password)


if username in user_acct and password == user_acct[username]:
>      print(prompt1 + "Enter en at this prompt" +"\n")
>      print(prompt2 + "Enter conf t at this prompt" + "\n")
>      print(prompt3 + "\n")
> else:
>      
>      print('Invalid Login... Please Try Again')close()

Shouldn't you check the login details before passing it
to the telnet host?

Also note you are not storing anything you get from the
host so you are just checking your own local data.

I don't really know what this is supposed to be doing.


I'd suggest starting slow. Create a script that simply
logs in with a hard coded name/password and then prints
a succcess/fail message and logs out again.

Once you know you can connect and login then you can start
to think about extra features.

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



From alan.gauld at yahoo.co.uk  Tue May 24 15:48:39 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 24 May 2016 20:48:39 +0100
Subject: [Tutor] Learning Regular Expressions
In-Reply-To: <57437F6D.9010808@gmail.com>
References: <57437F6D.9010808@gmail.com>
Message-ID: <ni2b6l$a9j$1@ger.gmane.org>

On 23/05/16 23:08, Terry--gmail wrote:

> scripted worked great without the notes!  I'd like to know what it is in 
> the below Tripple-Quoted section that is causing me this problem...if 
> anyone recognizes. In IDLE's script file..._it's all colored green_, 
> which I thought meant Python was going to ignore everything between the 
> tripple-quotes! 

Its all green forv me too and it runs perfectly - as in it does
absolutly nothing.


And if I add print('hello world') at the end it prionts ok too.

I even tried assigning your docsstring to a variable and printing
that and it too worked.

Linux Mint 17
Python 3.4.3
IDLE 3

So I don't think this is your entire problem. Maybe you should
show us some code that actually causes the error?

> But if I run just the below portion of the script in 
> it's own file, I get the same While Scanning Tripple-Quotes error.

As above, it runs silently for me.

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



From alan.gauld at yahoo.co.uk  Tue May 24 20:10:52 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 25 May 2016 01:10:52 +0100
Subject: [Tutor] Fwd: Re:  I've subscribed to your service,
 no confirmation yet. I'm looking for a tutor and I need help with
 some code.
In-Reply-To: <2132829516.74640.1464127652150.JavaMail.yahoo@mail.yahoo.com>
References: <2132829516.74640.1464127652150.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <5744ED8C.2090608@yahoo.co.uk>

Forwarding to list...



-------- Forwarded Message --------

The box is my controller with and IP address, I'm doing all this from my
windows 7 PC. 
As I said I can type telnet 10.35.56.90 in the dos cmd prompt and get to
my controller. I wrote a python script with the user_acct dictionary.

I do get the >>> in the python IDLE but within my python script/file can
I telnet to my controller? Keep in mind when I do log into my controller
it's command line driven.

I have python 2.7 and 3.5 installed on my windows 7 pc.

So you're saying open the python IDLE and import the telnet lib and just
type; telnet 10.45.34.80 and I'll be able to get to my controller???

Thank you for helping me :)
 
...you cannot direct the wind but you can adjust your sails...
 
 
*Angelia Spencer (Angie)*


------------------------------------------------------------------------
*From:* Alan Gauld via Tutor <tutor at python.org>
*To:* tutor at python.org
*Sent:* Tuesday, May 24, 2016 2:38 PM
*Subject:* Re: [Tutor] I've subscribed to your service, no confirmation
yet. I'm looking for a tutor and I need help with some code.

Re your subject...
This is a mailing list. You subscribe and you should receive
mails sent to the list.
If you have a question send it to the list (like you did here)
and one or more of the list members will hopefully respond.
The more specific your question the more precise will be the response.
Try to include OS, Python version, any error messages(in full)

Now to your message...

On 24/05/16 18:06, Angelia Spencer via Tutor wrote:
>  I'm trying to telnet to my box.

What is your "box"? A server somewhere? Running what OS?
Where are you telnetting from?

> When I do this in DOS it's simple, I even have a blinking cursor
> for me to type in commands for each response.

I assume you mean you telnet from a Windows PC and login to your server
and get an OS command prompt? (Possibly running bash?)

> Not so for python.

What does this mean? If you run the python command on your DOS
console you should get a prompt like

>>>

at which you can type in commands.

If python is installed on your "box" then telnet to the box
and at the OS prompt type python.

If that doesn't work for you, you will need to give us a lot more
information about how you installed Python, which version, how
you are trying to run python etc.

> I have a dictionary "user_acct" which has the username
> and password in it.

> My box is interactive, I must be able to type in commands

Again we have no idea what your "box" is. What do you mean
its interactive, nearly all computers are to some extent?

> and I don't know how to do this in python.

While python does have an interactive mode (the >>> prompt) it's not
normally used that way. Usually you put your code in a script file
(ending .py) and run it from an OS prompt (or file manager) like

C:\WINDOWS> python myscript.py

> 1st prompt = Username:2nd prompt = Password:
>
> After this my box's output looks like this:Last Login Date      : May
24 2016 09:42:08
> Last Login Type      : IP Session(CLI)
> Login Failures      : 0 (Since Last Login)
>                      : 0 (Total for Account)
> TA5000>then I type en and get
> TA5000# then I type conf t and getTA5000(config)#

OK, I'm guessing that's a Unix like system but I'm not sure.

> My code is below:

How are you trying to run this?
Where is it stored?
Where is python installed?

> import getpass
> import sys
> import telnetlib

username = input()

> password = input()
> tid = 'TA5000'
> first_prompt = '>' # type 'en' at this prompt
> second_prompt = '#' # type 'conf t' at this prompt
> third_prompt = '(config)'
> prompt1 = tid + first_prompt
> prompt2 = tid + second_prompt
> prompt3 = tid + third_prompt + second_prompt
> user_acct =
{'ADMIN':'PASSWORD','ADTRAN':'BOSCO','READONLY':'PASSWORD','READWRITE':'PASSWORD','TEST':'PASSWORD','guest':'PASSWORD','':'PASSWORD'}
> host = "10.51.18.88"
> #username = "ADMIN" + newline
> #password = "PASSWORD" + newline
> tn = telnetlib.Telnet(host,"23")
> open()

That calls the builtin open() function without arguments which should
cause an error. Do you get an error message?

You probably wanted

tn.open()

> tn.read_until("Username: ")
> tn.write(username)
> tn.read_until("Password: ")
> tn.write(password)


if username in user_acct and password == user_acct[username]:
>      print(prompt1 + "Enter en at this prompt" +"\n")
>      print(prompt2 + "Enter conf t at this prompt" + "\n")
>      print(prompt3 + "\n")
> else:
>     
>      print('Invalid Login... Please Try Again')close()

Shouldn't you check the login details before passing it
to the telnet host?

Also note you are not storing anything you get from the
host so you are just checking your own local data.

I don't really know what this is supposed to be doing.


I'd suggest starting slow. Create a script that simply
logs in with a hard coded name/password and then prints
a succcess/fail message and logs out again.

Once you know you can connect and login then you can start
to think about extra features.

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



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





From alan.gauld at yahoo.co.uk  Tue May 24 20:08:29 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 25 May 2016 01:08:29 +0100
Subject: [Tutor] Fwd: Re:  I've subscribed to your service,
 no confirmation yet. I'm looking for a tutor and I need help with
 some code.
In-Reply-To: <1344475984.99053.1464128903127.JavaMail.yahoo@mail.yahoo.com>
References: <1344475984.99053.1464128903127.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <5744ECFD.8030202@yahoo.co.uk>

Forwarding to the list.
Please use reply-all to respond to list messages.

Also please use plain text as HTML messages often result in
code listings being corrupted, especially the spacing, which
is very important in Python.


-------- Forwarded Message --------

> I just opened the python IDLE 3.5 on my MAC and I imported telnet.lib.
> On the next line I typed telnet 192.09.168.55 and I got an error. It said
> invalid syntax. I'm trying to telnet to my other MAC here at home, just
> to see if I can connect.

You cannot just type telnet commands into Python you need to use
the telnet API. (Type help(telnetlib) at the >>> prompt or visit the
modules documentation page)

A typical session might look something like:

>>> import telnetlib
>>> tn = telnetlib.Telnet('myhost.com')
>>> response = tn.read()
>>> print(response)
..... some stuff here ....
>>> tn.close()

That's assuming you have telnet access to myhost.com of course, many sites
don't allow it because of the security issues associated with telnet.
ssh is
probably a better bet.

But in either case don't expect a telnet interactive session - that's
what the
telnet command (or ssh) is for. Python gives you the ability to automate a
session, with no human interactivity required. If you want to interact
you'll
need to read the output and check for prompts from the host then relay
those prompts to your user from Python.
 

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



From ben+python at benfinney.id.au  Tue May 24 21:07:54 2016
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 25 May 2016 11:07:54 +1000
Subject: [Tutor] Getting started in testing
References: <alpine.LRH.2.00.1605191228410.12694@aqua.rahul.net>
 <alpine.LRH.2.00.1605231624290.31398@aqua.rahul.net>
Message-ID: <85mvnf9c7p.fsf@benfinney.id.au>

Terry Carroll <carroll at tjc.com> writes:

> Thanks to Alan, Danny, Albert-Jan and Ben for their suggestions. I've
> now gotten my feet wet in unittest and have gone from not quite
> knowing where to start to making substantial progress, with a small
> suite of tests up and running.

Great start!

Do keep in mind that unit tests are only one kind of test ? the most
detailed, testing a single assertion about a single unit of code. A good
test suite has tests written to test higher groups of functionality too.

-- 
 \        ?A life spent making mistakes is not only most honorable but |
  `\          more useful than a life spent doing nothing.? ?anonymous |
_o__)                                                                  |
Ben Finney


From crusier at gmail.com  Tue May 24 23:11:55 2016
From: crusier at gmail.com (Crusier)
Date: Wed, 25 May 2016 11:11:55 +0800
Subject: [Tutor] Web Page Scraping
In-Reply-To: <CANLXbfDtHWxDoOZShgxZ-76g+hRkW9Bm9ZXg7mEv1JcXak=1kQ@mail.gmail.com>
References: <CAC7HCj9y0t+=hNOzG6rJv=nsXydABA6kHFzYe2XP+y7Asa=oTQ@mail.gmail.com>
 <CANLXbfC==2rJs5hXWymbUK6Tx+mMk9jwkem7amTxrq5M7sBx2g@mail.gmail.com>
 <CANLXbfDtHWxDoOZShgxZ-76g+hRkW9Bm9ZXg7mEv1JcXak=1kQ@mail.gmail.com>
Message-ID: <CAC7HCj8a7cxAkZk5y9-RSRxEwUSbr14qYeSUkimChzYZx-1OWQ@mail.gmail.com>

Hi Walter,

Thank you for taking your time to do all the explanation.

Have a great day.

Cheers,
Hank

On Tue, May 24, 2016 at 10:45 PM, Walter Prins <wprins at gmail.com> wrote:
> On 24 May 2016 at 15:37, Walter Prins <wprins at gmail.com> wrote:
>>             print(name1.encode(sys.stdout.encoding, "backslashreplace")) #****
>
> I forgot to mention, you might want to read the following documentation page:
>
> https://docs.python.org/3/howto/unicode.html
>
> (good luck.....)
>
> W

From alan.gauld at yahoo.co.uk  Wed May 25 04:21:39 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 25 May 2016 09:21:39 +0100
Subject: [Tutor] Fwd: Re: I've subscribed to your service,
 no confirmation yet. I'm looking for a tutor and I need help with
 some code.
In-Reply-To: <5744ED8C.2090608@yahoo.co.uk>
References: <2132829516.74640.1464127652150.JavaMail.yahoo@mail.yahoo.com>
 <5744ED8C.2090608@yahoo.co.uk>
Message-ID: <ni3nag$vod$1@ger.gmane.org>


> I do get the >>> in the python IDLE but within my python script/file can
> I telnet to my controller? Keep in mind when I do log into my controller
> it's command line driven.

One thing that occurred to me is that you may be better off using the
subprocess module to start an interactive telnet process. It's less easy
to control the session programmatically than with telnetlib
but it would give you the interactive element you seem to want.

It just depends on what you are trying to achieve...

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



From ahall at autodist.com  Wed May 25 12:05:16 2016
From: ahall at autodist.com (Alex Hall)
Date: Wed, 25 May 2016 12:05:16 -0400
Subject: [Tutor] Baffling problem with a list of objects sharing a property
Message-ID: <CA+Q8_JdKHno8uvXmgwDsWGeu-U7vdKZpEAWnsD2x3v9kxuDSNA@mail.gmail.com>

Hello all,
I've used Python off and on for years, and consider myself pretty good with
it. I was on this list quite a while ago and learned a lot, but hadn't used
Python for a while so eventually unsubscribed.

Now I'm using Python for work, and have run into a problem that has me
baffled. It's as though a bunch of class instances in a list are sharing a
single property. Have a look at this script:


class Test(object):
 def __init__(self, name, paths=[]):
  self.name = name
  self.paths = paths

 def __str__(self):
  return "Name: {name}. Path count: {paths}.".format(name=self.name,
paths=len(self.paths))

#end class Test

tests = [
 Test("a"),
 Test("b"),
 Test("c"),
]

for t in tests:
 print t
 t.paths.append("a")
 print t

If you run that, something odd happens. Instead of each Test instance
getting one item appended to its "paths" property, Test C ends up with
three, B with 2, and A with 1. It's as though appending to t.paths appends
to the paths property for all the instances in the list, not just the
current one. I've been working on this for over an hour and just can't
figure out what the deal is. I'm emailing spreadsheets using Python, and
this problem is causing all the spreadsheets to be emailed to everyone,
when it should be just one spreadsheet per person. Oh, the same problem
happens if you remove (object) from the class definition, and if your loop
is instead:

for i in range(len(tests)):
 print tests[i]
 tests[i].paths.append("a")
 print tests[i]

If anyone can explain what's happening, I'd very much appreciate it. I'm on
Windows 7, Python 2.7.11. Thanks.


-- 
Alex Hall
Automatic Distributors, IT department
ahall at autodist.com

From alan.gauld at yahoo.co.uk  Wed May 25 12:19:19 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 25 May 2016 17:19:19 +0100
Subject: [Tutor] Fwd: Re: I've subscribed to your service,
 no confirmation yet. I'm looking for a tutor and I need help with
 some code.
In-Reply-To: <1614460471.444817.1464181892642.JavaMail.yahoo@mail.yahoo.com>
References: <1344475984.99053.1464128903127.JavaMail.yahoo@mail.yahoo.com>
 <5744ECFD.8030202@yahoo.co.uk>
 <1614460471.444817.1464181892642.JavaMail.yahoo@mail.yahoo.com>
Message-ID: <5745D087.6040709@yahoo.co.uk>

On 25/05/16 14:11, Angelia Spencer wrote:
> in your code below you're telnet-ing to a website,

No, I'm telnetting to a server with the IP address mysite.com
(which is obviously fictitious, but could be any valid IP address).
There is nothing that says it's a web site. (And even some web
sites might allow telnet access, that's just an admin thing)

> I am not and when I type, >>> response = tn.read(). I get an error.
>
> >>> response=tn.read()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> AttributeError: Telnet instance has no attribute 'read'
> >>>

Sorry, I misremembered the method name.
Here is an actual session using a public telnet site:

>>> import telnetlib
>>> tn = telnetlib.Telnet('telehack.com')
>>> response = tn.read_some()
>>>b'\r\nConnected to TELEH'
b'\r\nConnected to TELEH'
>>> tn.close()
>>>


There are a bunch of other read_xxxx() methods, you
need to read the help page to find out how they differ.
-- Alan G Author of the Learn to Program web site
http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow
my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos

From __peter__ at web.de  Wed May 25 12:23:35 2016
From: __peter__ at web.de (Peter Otten)
Date: Wed, 25 May 2016 18:23:35 +0200
Subject: [Tutor] Baffling problem with a list of objects sharing a
 property
References: <CA+Q8_JdKHno8uvXmgwDsWGeu-U7vdKZpEAWnsD2x3v9kxuDSNA@mail.gmail.com>
Message-ID: <ni4ji8$n7f$1@ger.gmane.org>

Alex Hall wrote:

> class Test(object):
>  def __init__(self, name, paths=[]):

https://docs.python.org/2/faq/programming.html#why-are-default-values-shared-between-objects




From alan.gauld at yahoo.co.uk  Wed May 25 12:26:10 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 25 May 2016 17:26:10 +0100
Subject: [Tutor] Baffling problem with a list of objects sharing a
 property
In-Reply-To: <CA+Q8_JdKHno8uvXmgwDsWGeu-U7vdKZpEAWnsD2x3v9kxuDSNA@mail.gmail.com>
References: <CA+Q8_JdKHno8uvXmgwDsWGeu-U7vdKZpEAWnsD2x3v9kxuDSNA@mail.gmail.com>
Message-ID: <ni4jn0$qs$1@ger.gmane.org>

On 25/05/16 17:05, Alex Hall wrote:

> Python for a while so eventually unsubscribed.

Welcome back Alex :-)

> Now I'm using Python for work, and have run into a problem that has me
> baffled. It's as though a bunch of class instances in a list are sharing a
> single property. 

They are. You've stiumbled on one of those Python peculiarities of
implementation that can be useful and annoying in equal measure.

> class Test(object):
>  def __init__(self, name, paths=[]):
>   self.name = name
>   self.paths = paths

When you give a function/method a default value that same object is used
for *every* invocation of the method where the default applies.
So that list you create is shared and if any instance adds anything
to it, it will appear in every other instance too! So unless you
want that behaviour its usually better to make default values
immutable or None, then in the code assign the actual value,
like:

def foo(v = None):
    if not v: v = []  # or whatever mutable value you need.

HTH

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



From alan.gauld at yahoo.co.uk  Wed May 25 12:29:05 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 25 May 2016 17:29:05 +0100
Subject: [Tutor] Fwd: Re: I've subscribed to your service,
 no confirmation yet. I'm looking for a tutor and I need help with
 some code.
In-Reply-To: <5745D087.6040709@yahoo.co.uk>
References: <1344475984.99053.1464128903127.JavaMail.yahoo@mail.yahoo.com>
 <5744ECFD.8030202@yahoo.co.uk>
 <1614460471.444817.1464181892642.JavaMail.yahoo@mail.yahoo.com>
 <5745D087.6040709@yahoo.co.uk>
Message-ID: <ni4jse$qs$2@ger.gmane.org>

On 25/05/16 17:19, Alan Gauld via Tutor wrote:

> Here is an actual session using a public telnet site:
> 
>>>> import telnetlib
>>>> tn = telnetlib.Telnet('telehack.com')
>>>> response = tn.read_some()
>>>> b'\r\nConnected to TELEH'

Oops! a cut n paste error. That line should be:

>>> print(response[:20])
b'\r\nConnected to TELEH'


>>>> tn.close()


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



From ahall at autodist.com  Wed May 25 14:11:01 2016
From: ahall at autodist.com (Alex Hall)
Date: Wed, 25 May 2016 14:11:01 -0400
Subject: [Tutor] Logging exceptions, but getting stderr output instead
Message-ID: <CA+Q8_JfvkgKKNhhxeCddFCD3+sXWr5YtLB=O2Th0SDdD2OKfSA@mail.gmail.com>

Hello again list,
I didn't expect to be back so soon. :) I'm trying to log my new script, and
logger.info() works fine. However, logger.exception() doesn't; I see the
exception print to stderr, and it never appears in the log. Oddly, info
messages after that appear in the shell and in my log, whereas normally
they are only in the log. Here's my logger setup:

logger = logging.getLogger(appName)
logger.setLevel(logging.DEBUG)
infoLogFormatter = logging.Formatter("%(asctime)s\n%(name)s, %(levelname)s:
%(message)s", datefmt = "%I:%M:%S %p, %B %d, %Y")
infoLogFileName = appName+".log"
infoFileHandler = logging.FileHandler(infoLogFileName, mode="w")
infoFileHandler.level = logging.INFO
infoFileHandler.setFormatter(infoLogFormatter)
logger.addHandler(infoFileHandler)

Then, I deliberately called a non-existant function:

for rep in reps:
 try:
  workbook = xlsxwriter.Workbook(workbookName)
  worksheet = workbook.addWorksheet(rep.name) #should be add_worksheet, so
this errors out
 except:
  logging.exception("Error generating spreadsheet for {name}".format(name=
rep.name))

The string I pass to logging.exception, along with the stack trace, print
to the command line and not to my log file. Other logging.info() calls also
print to the command line, but they also appear in the log. I haven't done
much with logging before, and what I have done has been debug only, never
exceptions. The resolution to this will likely be obvious, but when I
looked it up, I found only information about how to log exceptions. No one
seems to have the problem of exceptions not being logged correctly.

As a quick aside, is there an easy way to halt script execution for some
exceptions? Right now, catching them means that execution continues, but I
sometimes want to log the problem and then abort the script, as the error
means it shouldn't continue. Thanks.


-- 
Alex Hall
Automatic Distributors, IT department
ahall at autodist.com

From alan.gauld at yahoo.co.uk  Wed May 25 15:37:36 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Wed, 25 May 2016 20:37:36 +0100
Subject: [Tutor] Logging exceptions, but getting stderr output instead
In-Reply-To: <CA+Q8_JfvkgKKNhhxeCddFCD3+sXWr5YtLB=O2Th0SDdD2OKfSA@mail.gmail.com>
References: <CA+Q8_JfvkgKKNhhxeCddFCD3+sXWr5YtLB=O2Th0SDdD2OKfSA@mail.gmail.com>
Message-ID: <ni4utu$svv$1@ger.gmane.org>

On 25/05/16 19:11, Alex Hall wrote:

> As a quick aside, is there an easy way to halt script execution for some
> exceptions? Right now, catching them means that execution continues, but I
> sometimes want to log the problem and then abort the script, as the error
> means it shouldn't continue. Thanks.

I'm not sure what the issue is here.
Can't you just exit in the normal fashion using

sys.exit()
or
raise SystemExit?

I feel I must be missing something?

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



From __peter__ at web.de  Wed May 25 15:51:04 2016
From: __peter__ at web.de (Peter Otten)
Date: Wed, 25 May 2016 21:51:04 +0200
Subject: [Tutor] Logging exceptions, but getting stderr output instead
References: <CA+Q8_JfvkgKKNhhxeCddFCD3+sXWr5YtLB=O2Th0SDdD2OKfSA@mail.gmail.com>
Message-ID: <ni4vn8$7j4$1@ger.gmane.org>

Alex Hall wrote:

> Hello again list,
> I didn't expect to be back so soon. :) I'm trying to log my new script,
> and logger.info() works fine. However, logger.exception() doesn't; I see
> the exception print to stderr, and it never appears in the log. Oddly,
> info messages after that appear in the shell and in my log, whereas
> normally they are only in the log. Here's my logger setup:
> 
> logger = logging.getLogger(appName)
> logger.setLevel(logging.DEBUG)
> infoLogFormatter = logging.Formatter("%(asctime)s\n%(name)s,
> %(levelname)s: %(message)s", datefmt = "%I:%M:%S %p, %B %d, %Y")
> infoLogFileName = appName+".log"
> infoFileHandler = logging.FileHandler(infoLogFileName, mode="w")
> infoFileHandler.level = logging.INFO
> infoFileHandler.setFormatter(infoLogFormatter)
> logger.addHandler(infoFileHandler)
> 
> Then, I deliberately called a non-existant function:
> 
> for rep in reps:
>  try:
>   workbook = xlsxwriter.Workbook(workbookName)
>   worksheet = workbook.addWorksheet(rep.name) #should be add_worksheet, so
> this errors out
>  except:
>   logging.exception("Error generating spreadsheet for {name}".format(name=
> rep.name))

That should be logger.exception(...); logging.exception() logs to the root 
logger.

Unless you know what you are doing I'd still suggest that you add your 
handler(s) to the root logger. In most cases calling logging.basicConfig() 
is probably good enough...


From ahall at autodist.com  Wed May 25 15:13:23 2016
From: ahall at autodist.com (Alex Hall)
Date: Wed, 25 May 2016 15:13:23 -0400
Subject: [Tutor] Logging exceptions, but getting stderr output instead
In-Reply-To: <CA+Q8_JfvkgKKNhhxeCddFCD3+sXWr5YtLB=O2Th0SDdD2OKfSA@mail.gmail.com>
References: <CA+Q8_JfvkgKKNhhxeCddFCD3+sXWr5YtLB=O2Th0SDdD2OKfSA@mail.gmail.com>
Message-ID: <CA+Q8_JeCubfRHHvfnCfx0F_ENLhQ=yy6-T2XM+VZhVe7nysPAw@mail.gmail.com>

Well, I found the major problem: I had
logging.exception()
not
logger.exception()
All I can say is, with the screen reader I'm using, they sound similar.
Things are now working as expected. I'm still wondering about stopping
execution, though: call exit(), raise, or some other way?


On Wed, May 25, 2016 at 2:11 PM, Alex Hall <ahall at autodist.com> wrote:

> Hello again list,
> I didn't expect to be back so soon. :) I'm trying to log my new script,
> and logger.info() works fine. However, logger.exception() doesn't; I see
> the exception print to stderr, and it never appears in the log. Oddly, info
> messages after that appear in the shell and in my log, whereas normally
> they are only in the log. Here's my logger setup:
>
> logger = logging.getLogger(appName)
> logger.setLevel(logging.DEBUG)
> infoLogFormatter = logging.Formatter("%(asctime)s\n%(name)s,
> %(levelname)s: %(message)s", datefmt = "%I:%M:%S %p, %B %d, %Y")
> infoLogFileName = appName+".log"
> infoFileHandler = logging.FileHandler(infoLogFileName, mode="w")
> infoFileHandler.level = logging.INFO
> infoFileHandler.setFormatter(infoLogFormatter)
> logger.addHandler(infoFileHandler)
>
> Then, I deliberately called a non-existant function:
>
> for rep in reps:
>  try:
>   workbook = xlsxwriter.Workbook(workbookName)
>   worksheet = workbook.addWorksheet(rep.name) #should be add_worksheet,
> so this errors out
>  except:
>   logging.exception("Error generating spreadsheet for {name}".format(name=
> rep.name))
>
> The string I pass to logging.exception, along with the stack trace, print
> to the command line and not to my log file. Other logging.info() calls
> also print to the command line, but they also appear in the log. I haven't
> done much with logging before, and what I have done has been debug only,
> never exceptions. The resolution to this will likely be obvious, but when I
> looked it up, I found only information about how to log exceptions. No one
> seems to have the problem of exceptions not being logged correctly.
>
> As a quick aside, is there an easy way to halt script execution for some
> exceptions? Right now, catching them means that execution continues, but I
> sometimes want to log the problem and then abort the script, as the error
> means it shouldn't continue. Thanks.
>
>
> --
> Alex Hall
> Automatic Distributors, IT department
> ahall at autodist.com
>



-- 
Alex Hall
Automatic Distributors, IT department
ahall at autodist.com

From ahall at autodist.com  Wed May 25 15:44:28 2016
From: ahall at autodist.com (Alex Hall)
Date: Wed, 25 May 2016 15:44:28 -0400
Subject: [Tutor] Logging exceptions, but getting stderr output instead
In-Reply-To: <ni4utu$svv$1@ger.gmane.org>
References: <CA+Q8_JfvkgKKNhhxeCddFCD3+sXWr5YtLB=O2Th0SDdD2OKfSA@mail.gmail.com>
 <ni4utu$svv$1@ger.gmane.org>
Message-ID: <CA+Q8_Jf+H3QA+cMbnMqBNsNFwjeqSYwrv5jv=HROUV7-a_iOSA@mail.gmail.com>

You're not missing anything; I wasn't clear. I wasn't sure if raise or
sys.exit(1) were the preferred ways, or if there was some other way I
didn't know about. I've never had to force a script to halt before, at
least not one I mean to schedule to run on its own once a day, so wanted to
check that those are indeed the recommended ways.

On Wed, May 25, 2016 at 3:37 PM, Alan Gauld via Tutor <tutor at python.org>
wrote:

> On 25/05/16 19:11, Alex Hall wrote:
>
> > As a quick aside, is there an easy way to halt script execution for some
> > exceptions? Right now, catching them means that execution continues, but
> I
> > sometimes want to log the problem and then abort the script, as the error
> > means it shouldn't continue. Thanks.
>
> I'm not sure what the issue is here.
> Can't you just exit in the normal fashion using
>
> sys.exit()
> or
> raise SystemExit?
>
> I feel I must be missing something?
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Alex Hall
Automatic Distributors, IT department
ahall at autodist.com

From carroll at tjc.com  Wed May 25 20:35:25 2016
From: carroll at tjc.com (Terry Carroll)
Date: Wed, 25 May 2016 17:35:25 -0700 (PDT)
Subject: [Tutor] Logging exceptions, but getting stderr output instead
In-Reply-To: <CA+Q8_Jf+H3QA+cMbnMqBNsNFwjeqSYwrv5jv=HROUV7-a_iOSA@mail.gmail.com>
References: <CA+Q8_JfvkgKKNhhxeCddFCD3+sXWr5YtLB=O2Th0SDdD2OKfSA@mail.gmail.com>
 <ni4utu$svv$1@ger.gmane.org>
 <CA+Q8_Jf+H3QA+cMbnMqBNsNFwjeqSYwrv5jv=HROUV7-a_iOSA@mail.gmail.com>
Message-ID: <alpine.LRH.2.00.1605251731300.29439@aqua.rahul.net>

On Wed, 25 May 2016, Alex Hall wrote:

> You're not missing anything; I wasn't clear. I wasn't sure if raise or
> sys.exit(1) were the preferred ways, or if there was some other way I
> didn't know about.

If you're aborting because of the exception after unsuccessfully trying to 
handle it, you can always just use "raise" with no operands, which will 
re-raise the underlying exception. That's what I usually do:

try:
     1/0
except ZeroDivisionError:
     print "oops."
     raise

prints:

oops.
Traceback (most recent call last):
   File "[...]\test.py", line 2, 
in <module>
     1/0
ZeroDivisionError: integer division or modulo by zero


From dyoo at hashcollision.org  Thu May 26 14:25:07 2016
From: dyoo at hashcollision.org (Danny Yoo)
Date: Thu, 26 May 2016 11:25:07 -0700
Subject: [Tutor] Baffling problem with a list of objects sharing a
 property
In-Reply-To: <ni4jn0$qs$1@ger.gmane.org>
References: <CA+Q8_JdKHno8uvXmgwDsWGeu-U7vdKZpEAWnsD2x3v9kxuDSNA@mail.gmail.com>
 <ni4jn0$qs$1@ger.gmane.org>
Message-ID: <CAGZAPF67+AwzsbK8LdkmvmVAVvnSV4NLGmqKnQ0Nm-CcUeQkgQ@mail.gmail.com>

> They are. You've stiumbled on one of those Python peculiarities of
> implementation that can be useful and annoying in equal measure.
>
>> class Test(object):
>>  def __init__(self, name, paths=[]):
>>   self.name = name
>>   self.paths = paths
>
> When you give a function/method a default value that same object is used
> for *every* invocation of the method where the default applies.


By the way, this is one of the things that tools like pylint
(https://www.pylint.org/) will warn about.

    http://pylint-messages.wikidot.com/messages:w0102

Just to note that there are external "lint" tools that can help catch
this class of problems automatically.



Best of wishes!

From maxjegers at gmail.com  Thu May 26 18:34:04 2016
From: maxjegers at gmail.com (Max Jegers)
Date: Thu, 26 May 2016 16:34:04 -0600
Subject: [Tutor] Newcomer with organizational questions
Message-ID: <CANdyN1nLietHqDTN+mp4nmd0tE4bHrzG6cbYjWcsKj=ioPjmcA@mail.gmail.com>

Hi,


I am a newcomer who asked a first question here at Tutor. Soon I received a
very good answer from a tutor and put an effort to understand it. After
that I wrote a reply with a thank you and a follow-up question, only to
discover that I don?t see a way to send it.


I need to say I did not write to maillist forums before, only to forums
with Post button right there:).



I reread *tutor-**bounces* auto-response, then did some googling and
realized that I may need to subscribe. So I did on Sunday May 22, and the
webpage said: ?*Your subscription request has been received, and will soon
be acted upon. Depending on the configuration of this mailing list, your
subscription request may have to be first confirmed by you via email, or
approved by the list moderator. If confirmation is required, you will soon
get a confirmation email which contains further instructions.*?

Main question: Should I wait more or I am missing something I need to do at
my end?

My purpose is to post a reply in a particular subject I initiated.



Please note that I did not receive anything from a tutor in my email other
than *tutor-bounces* auto-response. I use Gmail.



Other organizational questions:

-       -   May I attach a file to a message? Some Python libraries are
quite big (50 pages in my case), however it may be not difficult for an
expert to answer a question if he/she has a full library. At the same time,
it seems inconsiderate and impractical to paste 50 pages into a message.

-       -   Can I paste not in plain text ? using fonts etc?

-       -   May I ask a follow-up question in the same thread, or should I
start a new one?

-       -   Is this ok to post a message that contains thank you only, or
these messages have to be deleted by moderators (like on stackoverflow.com?)

I believe first I was able to see a tutor?s response on external website:
https://code.activestate.com/lists/python-tutor/107992/  - and much later
on mail.python.org. Is this persistent behaviour?

Possibly, all this is answered in a document somewhere?



Thank you for your time.

From ben+python at benfinney.id.au  Thu May 26 20:08:37 2016
From: ben+python at benfinney.id.au (Ben Finney)
Date: Fri, 27 May 2016 10:08:37 +1000
Subject: [Tutor] Newcomer with organizational questions
References: <CANdyN1nLietHqDTN+mp4nmd0tE4bHrzG6cbYjWcsKj=ioPjmcA@mail.gmail.com>
Message-ID: <858tyw9xbu.fsf@benfinney.id.au>

Max Jegers <maxjegers at gmail.com> writes:

> I am a newcomer who asked a first question here at Tutor. Soon I
> received a very good answer from a tutor and put an effort to
> understand it.

Welcome, and I'm glad you had a positive experience finding help here!

> After that I wrote a reply with a thank you and a follow-up question,
> only to discover that I don?t see a way to send it.

This is an email forum; you compose a reply by using the ?Reply To List?
command in your email client.

If you don't have such a command in your email client:

* Complain explicitly to whoever makes your email client. Reply To List
  is a standard feature which works correctly in any decent email client
  for decades.

* Consider using a better email client. (You don't have to change email
  addresses, just use a better program to operate your email.)

* As a last resort, you can manually fiddle with ?Reply To All? by
  removing individual email addresses, leaving only the list address to
  remain.

> I need to say I did not write to maillist forums before, only to
> forums with Post button right there:).

Email forums allow you to use the program you're already familiar with
for email, so IMO that makes them much preferable!

Here is <URL:https://www.mail-list.com/reply_in_a_mailing_list/> a
simple introduction to how reply works in an email forum.

-- 
 \                  ?It is ? incumbent upon us to recognize that it is |
  `\    inappropriate for religion to play any role in issues of state |
_o__)        [of] a modern democracy.? ?Lawrence M. Krauss, 2012-05-28 |
Ben Finney


From alan.gauld at yahoo.co.uk  Thu May 26 20:13:18 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Fri, 27 May 2016 01:13:18 +0100
Subject: [Tutor] Newcomer with organizational questions
In-Reply-To: <CANdyN1nLietHqDTN+mp4nmd0tE4bHrzG6cbYjWcsKj=ioPjmcA@mail.gmail.com>
References: <CANdyN1nLietHqDTN+mp4nmd0tE4bHrzG6cbYjWcsKj=ioPjmcA@mail.gmail.com>
Message-ID: <ni83eu$dq$1@ger.gmane.org>

On 26/05/16 23:34, Max Jegers wrote:

> that I wrote a reply with a thank you and a follow-up question, only to
> discover that I don?t see a way to send it.

A mailing list works by email, so you reply as you would to any email.
If you use Reply it goes to the person who sent the email.
If you use Reply All it goes to everyone who received the original
email, including the sender. In the case of a list it also includes the
list(and everyone on it.)

So the simplest solution is to always use Reply All (or if
you have the option, Reply List) and it will go to the list.

> I reread *tutor-**bounces* auto-response, then did some googling and
> realized that I may need to subscribe. So I did on Sunday May 22, and the
> webpage said: ?*Your subscription request has been received, and will soon
> be acted upon. Depending on the configuration of this mailing list, your
> subscription request may have to be first confirmed by you via email, or
> approved by the list moderator. If confirmation is required, you will soon
> get a confirmation email which contains further instructions.*?
> 
> Main question: Should I wait more or I am missing something I need to do at
> my end?

Nope, you are now subscribed.
However the default behaviour is to put new subscribers on a moderation
mode whereby all your early posts get caught in a queue and have to be
manually approved by a moderator. There are 3 of us but usually its me
:-) So I approved your post, it appeared on the list and I am now
replying to it.

> My purpose is to post a reply in a particular subject I initiated.

Find the mail and reply to it using Reply All.

A couple of important extra requirements
- Set your email to be plain text not HTML because HTML tends
  to mess the formatting which is critical for Python code.
  (You might be able to configure your mail tool to always
   use plain text for python.org posts.)
- Always include the code that's causing the problem
- Always include the full text of any errors you get
- Tell us your OS and Python version


> Please note that I did not receive anything from a tutor in my email other
> than *tutor-bounces* auto-response. I use Gmail.

That's just the server automated response.
Hopefully you receive this :-)

> -       -   May I attach a file to a message? Some Python libraries are
> quite big (50 pages in my case), however it may be not difficult for an
> expert to answer a question if he/she has a full library. At the same time,
> it seems inconsiderate and impractical to paste 50 pages into a message.

50 pages (how big is a page?)... probably too much.
Try to condense it by removing irrelevant bits.
My rule of thumb is up to 100 lines can goi in the message, bigger than
that [put it on a public pastebin and send a link.

Attachments are a bad idea because they often (but not always)
get stripped out for security reasons by the server.

> -       -   Can I paste not in plain text ? using fonts etc?

No, see above. HTML loses spaces etc and destroys formatting

You can use plain text mark ups such as _underline_ or *bold*

> -       -   May I ask a follow-up question in the same thread, or should I
> start a new one?

If its a new topic start a new thread.
If its a follow up on the same topic keep it in the same thread

> -       -   Is this ok to post a message that contains thank you only, or
> these messages have to be deleted by moderators (like on stackoverflow.com?)

It's not necessary every time but I certainly don't delete them
and if the response took a lot of work, maybe by multiple
contributors its good to let us know when you finally solve
the problem.

> I believe first I was able to see a tutor?s response on external website:
> https://code.activestate.com/lists/python-tutor/107992/  - and much later
> on mail.python.org. Is this persistent behaviour?

The list archives are available in several places including
python.org and activestate.com.

You can also receive (and reply to) list messages using usenet(NNTP) via
gmane. (Thats actually how I read the list.) They also provide
an archive of old posts.

Feel free to ask any more questions about the list or about Python
or programming in general.

-- 
Alan G
Python tutor list moderator

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



From robertvstepp at gmail.com  Sun May 29 00:33:17 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Sat, 28 May 2016 23:33:17 -0500
Subject: [Tutor] Correct use of model-view-controller design pattern
Message-ID: <CANDiX9JqTD+Pwhd2n0ivGF=HNAf4vy1M6Y60dN97PAFrV9nQjA@mail.gmail.com>

I am currently mulling over some information Alan passed along a while
back on using the model-view-controller design pattern (Would
'architectural pattern' be a better choice of phrase?).  I have been
doing my usual online readings and there is enough variation in what I
have read that I would like to post the simplest code I've been able
to come up with and see if my understanding of MVC is correct.

My current understanding is that the model contains program logic and
the data which the program logic manipulates.  The view is just the
interface with which the user interacts.  The controller ties things
together, refreshing the view appropriately, receiving messages from
the view when something there has been changed by the user,
interrogating the model when needed, and receiving the model's results
and refreshing the view appropriately.

In my simple code to follow, I have the contents of three files, which
I have named model.py, controller.py and view.py.  controller.py
starts program execution.  My intent is to keep each of the three as
independent of the others as I can manage, so that ideally, I could
modify one of them and not need (or minimally need) to modify the
other files.  So, for instance, I would hope that I could change the
command line view code to a GUI and avoid having to change model.py at
all and hopefully have very few alterations to controller.py, though I
am not certain I can achieve the ideal of no modifications to the
controller.

Disclaimer:  While I tried to write my best Python possible, I did not
go full-bore and filter input, add error handling, except incidentally
in one else block.
------------------------------------------------------------------------------------

controller.py:

#!/usr/bin/env python3

'''Simple controller program to explore the model-view-controller
design pattern.'''

import sys

import model
import view

def main():
    '''Start and run the program.'''

    option_num = view.main_menu()
    while True:
        if option_num == '1':
            diameter = float(view.diameter_prompt())
            circumf = model.circumference(diameter)
            view.display_circumference(str(diameter), str(circumf))
            option_num = view.main_menu()

        elif option_num == '2':
            view.display_exit_msg()
            sys.exit()

        else:
            title = 'WARNING!\n'
            msg = ('That is not a valid option number.\nPlease enter a valid ' +
                    'number and press <Enter>.')
            view.display_msg(title, msg)
            option_num = view.main_menu()

if __name__ == '__main__':
    main()
------------------------------------------------------------------------------------

model.py:

#!/usr/bin/env python3

'''Simple 'model' program to explore the model-view-controller design pattern.
'''

import math

PI = math.pi

def circumference(diameter):
    '''Calculate the circumference of a circle given its diameter.'''

    return PI * diameter
------------------------------------------------------------------------------------

view.py:

#!/usr/bin/env python3

'''Simple view program to explore the model-view-controller design pattern.'''

def main_menu():
    '''Display main menu of options and return entered option number.'''

    print('''
            Option 1:  Calculate the circumference of a circle.
            Option 2:  Exit this program.

            ''')
    main_menu_option = input('Enter an option number:  ')
    return main_menu_option

def diameter_prompt():
    '''Display a prompt to enter a diameter and return that value.'''

    print()
    diameter = input('Enter a diameter:  ')
    return diameter

def display_circumference(diameter, circumference):
    '''Display the circumference calculated from the user-entered diameter.'''

    print()
    print('You entered a diameter of', diameter, '.')
    print('The circumference corresponding to that diameter is',
            circumference, '.')

def display_exit_msg():
    '''Display exiting the program message.'''

    print()
    print('Exiting this program...\n')

def display_msg(title, msg):
    '''Display the passed title and message.'''

    print()
    print(title)
    print(msg)
------------------------------------------------------------------------------------

Does my code capture the essence of MVC?  Am I misunderstanding
anything or missing any nuances?  Would this code scale upward as I
would hope?  That is, if I chose to add more options as to what could
be done with the program, would I only need to add only the code for
the new functionality and not have to rewrite any existing code?  If I
were to change from CLI to GUI, would this similarly mean only a
rewrite of view.py without having to alter the other two files?

Some other questions:

1)  If I were to add code to filter user inputs, which file is the
logical place to place such code?  My current impression is that it
should go in the controller, but I could see it being in the view.
However, if I were to write a Validation class, I could see that as
having uses beyond checking just user input.

2)  Currently I am using a while loop in the controller to keep the
view 'alive'.  If I were to convert the view to a tkinter GUI, where
would the root.mainloop() statement go?  In the controller's main()
method?  What GUI-related stumbling blocks might I easily run into in
going from CLI to GUI with this existing code?

3)  If I were to add data files in place of (or in addition to) user
input, in which aspect of MVC would file I/O be handled?

I also welcome any Python-style critiques, including even the more nit
picky ones. ~(:>)

BTW, I did not attempt to write any classes as things seemed simple
enough that functions seemed more appropriate and straightforward to
me.  If that is a bad choice, please let me know!

TIA!

-- 
boB

From alan.gauld at yahoo.co.uk  Sun May 29 10:10:58 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Sun, 29 May 2016 15:10:58 +0100
Subject: [Tutor] Correct use of model-view-controller design pattern
In-Reply-To: <CANDiX9JqTD+Pwhd2n0ivGF=HNAf4vy1M6Y60dN97PAFrV9nQjA@mail.gmail.com>
References: <CANDiX9JqTD+Pwhd2n0ivGF=HNAf4vy1M6Y60dN97PAFrV9nQjA@mail.gmail.com>
Message-ID: <niet9i$eqp$1@ger.gmane.org>

On 29/05/16 05:33, boB Stepp wrote:
> I am currently mulling over some information Alan passed along a while
> back on using the model-view-controller design pattern (Would
> 'architectural pattern' be a better choice of phrase?).  

Either is appropriate. Design Pattern is more usual, largely because
it ws one of the first OOP patterns to be formally documented (in
the SmalltTalk world) and is included in the original Design
Patterns book by the GoF.

> My current understanding is that the model contains program logic and
> the data which the program logic manipulates.  

Correct, all the core entities which make up the program are represented
by models. Most things stored in a database will
have a corresponding model.

> The view is just the interface with which the user interacts.  

Specifically the visible part of the interface. the "presentation layer".

> The controller ties things together, refreshing the view appropriately, 
> receiving messages from the view when something there has
> been changed by the user, interrogating the model when needed,
> and receiving the model's results and refreshing the view
> appropriately.

The controller is where the confusion starts. Every implementation of
the MVC pattern seems to change the way the controller is defined. You
are broadly correct but some frameworks have a more view focussed
interpretation, others more model focused. For example some GUI
frameworks combine the view and controller concepts into a single Window
object (the Delphi/VB/MFC/OWL Windows GUI frameworks all
take that approach). The JSP type 1 framework is similar in that
the JSP page does both roles. But in the JSP type 2 framework the
controller is separated out into a distinct entity.

What everybody(?!) seems to agree on is that events generated by the
view are forwarded to a controller(*) which determines whether a model
needs to be involved and is so what method of which model needs to
be invoked.

(*)If the controller is embedded in the view object then that is
probably handled by an internal  superclass method of the framework
and based on an event table (similar to Tkinter's binding mechanism)

The model responds, but how the view is notified varies. In some cases
the views register with models and the model automatically sends
notification messages to all registered views (by-passing the
controller). In other cases the model si8mply sends a reply to the
controller that invoked it and the controller decides which views should
be updated.

Thee is a modern twist on the whole thing too, where a View-Model is
introduced. This is a model object that represents an aggregated view of
lower level models and is closely aligned to the fields on a view.
(Think of it being like a view table in a SQL database, an aggregation
of multiple tables via a SELECT statement) In this case the controller
may simply update the view-model and the view model will notify its
associated view(s) directly. This is most commonly seen in the
Web/Javascript world where the browser holds a View-Model in memory
which is updated based on JSON queries back to the server which
hosts the real models. This architecture allows rich web clients
to do things like sorting or filtering the data without going back
to the server.

Another common use of a view-model is for collections. You may have many
foo objects (each one a model in its own right) but a list
view of them only wants a single model to work with so you create a
view-model representing the collection of foo. Each foo is persisted
in the database but the collection is a more abstract entity being in
effect the table as a whole.

> In my simple code to follow, I have the contents of three files, which
> I have named model.py, controller.py and view.py.  controller.py
> starts program execution.  My intent is to keep each of the three as
> independent of the others as I can manage, so that ideally, I could
> modify one of them and not need (or minimally need) to modify the
> other files.  

In practice it's hard to separate the controller and view
entirely (which is why some frameworks combine them) but
it should definitely be possible to separate the models
from the more UI elements. What the controller does do
is allow you to swap different views within a single UI.
For example a list view, versus a form view versus a
graphical view, all of the same object or set of objects.

> controller.py:

> def main():
>     '''Start and run the program.'''
> 
>     option_num = view.main_menu()
>     while True:
>         if option_num == '1':
>             diameter = float(view.diameter_prompt())
>             circumf = model.circumference(diameter)
>             view.display_circumference(str(diameter), str(circumf))
>             option_num = view.main_menu()
> 
>         elif option_num == '2':
>             view.display_exit_msg()
>             sys.exit()
> 
>         else:
>             title = 'WARNING!\n'
>             msg = ('That is not a valid option number.\nPlease enter a valid ' +
>                     'number and press <Enter>.')
>             view.display_msg(title, msg)
>             option_num = view.main_menu()
> 
> if __name__ == '__main__':
>     main()
> ------------------------------------------------------------------------------------
> 
> model.py:
> 
> #!/usr/bin/env python3
> 
> '''Simple 'model' program to explore the model-view-controller design pattern.
> '''
> 
> import math
> 
> PI = math.pi
> 
> def circumference(diameter):
>     '''Calculate the circumference of a circle given its diameter.'''
> 
>     return PI * diameter
> ------------------------------------------------------------------------------------
> 
> view.py:
> 
> #!/usr/bin/env python3
> 
> '''Simple view program to explore the model-view-controller design pattern.'''
> 
> def main_menu():
>     '''Display main menu of options and return entered option number.'''
> 
>     print('''
>             Option 1:  Calculate the circumference of a circle.
>             Option 2:  Exit this program.
> 
>             ''')
>     main_menu_option = input('Enter an option number:  ')
>     return main_menu_option
> 
> def diameter_prompt():
>     '''Display a prompt to enter a diameter and return that value.'''
> 
>     print()
>     diameter = input('Enter a diameter:  ')
>     return diameter
> 
> def display_circumference(diameter, circumference):
>     '''Display the circumference calculated from the user-entered diameter.'''
> 
>     print()
>     print('You entered a diameter of', diameter, '.')
>     print('The circumference corresponding to that diameter is',
>             circumference, '.')
> 
> def display_exit_msg():
>     '''Display exiting the program message.'''
> 
>     print()
>     print('Exiting this program...\n')
> 
> def display_msg(title, msg):
>     '''Display the passed title and message.'''
> 
>     print()
>     print(title)
>     print(msg)
> ------------------------------------------------------------------------------------
> 
> Does my code capture the essence of MVC? 

For a CLI yes.

But I'd probably not make the controller the main() function.
Instead I'd have a separate main that constructed the objects.
The controller then has a handle_event() type method that
receives the event from the UI view.

So you make the view responsible for initiating the
event processing not the controller. The controller
then becomes a fairly simple validate-dispatch mechanism.

> anything or missing any nuances?  Would this code scale upward as I
> would hope?  

It would be a bit messy but could be adapted quite easily.
For example instead of the if/elif chain use a dictionary
for event dispatch.

> That is, if I chose to add more options as to what could
> be done with the program, would I only need to add only the code for
> the new functionality and not have to rewrite any existing code?  If I
> were to change from CLI to GUI, would this similarly mean only a
> rewrite of view.py without having to alter the other two files?

No because UI are event driven and have their own event loop.
That's why I'd move the main out of the controller. It's easier
to have the UI call your controller and just relay the event
info.

I gotta go so I'll get back to the other questions later if
nobody else has chimed in by then.


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



From __peter__ at web.de  Sun May 29 10:28:35 2016
From: __peter__ at web.de (Peter Otten)
Date: Sun, 29 May 2016 16:28:35 +0200
Subject: [Tutor] Correct use of model-view-controller design pattern
References: <CANDiX9JqTD+Pwhd2n0ivGF=HNAf4vy1M6Y60dN97PAFrV9nQjA@mail.gmail.com>
Message-ID: <nieuak$tu2$1@ger.gmane.org>

boB Stepp wrote:

[snip]

No direct answers to your questions, sorry;)

In my experience MVC is nearly always used to build GUIs and based on 
classes. The idea is that you can add multiple views to a model, a bar chart 
and a table of the values, sometimes at runtime. You may also swap out the 
model underneath the view, retrieve text from a file system or a database 
via the same interface. This is hard with modules.

The separation between view controller is often artificial or at least I 
always end up with a mix of these two components. The model-view split on 
the other side (also known as observer pattern) is straight-forward and 
helpful to produce cleaner code; but even between model and view the 
coupling tends to get stronger than you might wish.

Here's a commandline example with two views (the circle-drawing routine has 
to be fixed); in real life I would probably manipulate the model directly 
and omit the controller classes. There are two explict view classes, but the 

while True: ...

loop could also be seen as a view -- or rather the dreaded view/controller 
mix.

$ cat mvc_cli.py
#!/usr/bin/env python3


class CircleModel:
    def __init__(self, radius):
        self._radius = radius
        self.views = []

    def add(self, view):
        self.views.append(view)

    def changed(self):
        for view in self.views:
            view.changed(self)

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, radius):
        if self._radius != radius:
            self._radius = radius
            self.changed()


class CircleView:
    def __init__(self, model):
        self._model = None
        self.model = model
        self.changed(model)

    @property
    def model(self):
        return self._model

    @model.setter
    def model(self, model):
        if self._model is not None:
            raise NotImplementedError
        model.add(self)
        self._model = model

    def changed(self, model):
        """React to model changes."""


class RadiusDeltaController:
    def __init__(self, model, delta):
        self.model = model
        self.delta = delta

    def grow(self):
        self.model.radius += self.delta

    def shrink(self):
        self.model.radius -= self.delta


class RadiusController:
    def __init__(self, model):
        self.model = model

    def set_value(self, value):
        self.model.radius = value


def dist(ax, ay, bx, by):
    return ((ax-bx)**2 + (ay-by)**2)**.5


class CircleImageView(CircleView):

    def changed(self, model):
        self.update_radius(model.radius)

    def update_radius(self, radius):
        # FIXME
        diameter = 2*radius
        cx = cy = radius
        for row in range(diameter):
            for column in range(2*diameter):
                if dist(cx, cy, row, column/2) < radius:
                    print("*", end="")
                else:
                    print(" ", end="")
            print()


class CircleValueView(CircleView):
    def changed(self, model):
        print("Circle radius is now", model.radius)


if __name__ == "__main__":
    circle = CircleModel(5)
    image_view = CircleImageView(circle)
    value_view = CircleValueView(circle)
    rc = RadiusController(circle)
    dc = RadiusDeltaController(circle, 2)
    print("Model-View-Controler Demo")
    print("Enter an integer to set the circle radius")
    print("or 'grow' to increase the radius")
    print("or 'shrink' to decrease the radius")
    print("or 'add' to add another CircleValueView")
    while True:
        try:
            s = input("radius or 'grow' or 'shrink' or 'add': ")
        except KeyboardInterrupt:
            print("\nThat's all folks")
            break
        if s == "grow":
            dc.grow()
        elif s == "shrink":
            dc.shrink()
        elif s == "add":
            CircleValueView(circle)
        else:
            try:
                radius = int(s)
            except ValueError:
                print("don't know what to do with input {!r}".format(s))
            else:
                rc.set_value(radius)


Here's a sample session:
$ python3 mvc_cli.py 
                    
     ***********    
   ***************  
 *******************
 *******************
 *******************
 *******************
 *******************
   ***************  
     ***********    
Circle radius is now 5
Model-View-Controler Demo
Enter an integer to set the circle radius
or 'grow' to increase the radius
or 'shrink' to decrease the radius
or 'add' to add another CircleValueView
radius or 'grow' or 'shrink' or 'add': add
Circle radius is now 5
radius or 'grow' or 'shrink' or 'add': grow
                            
       ***************      
     *******************    
   ***********************  
  ************************* 
 ***************************
 ***************************
 ***************************
 ***************************
 ***************************
  ************************* 
   ***********************  
     *******************    
       ***************      
Circle radius is now 7
Circle radius is now 7
radius or 'grow' or 'shrink' or 'add': grow
                                    
          *****************         
       ***********************      
     ***************************    
    *****************************   
  ********************************* 
  ********************************* 
 ***********************************
 ***********************************
 ***********************************
 ***********************************
 ***********************************
  ********************************* 
  ********************************* 
    *****************************   
     ***************************    
       ***********************      
          *****************         
Circle radius is now 9
Circle radius is now 9
radius or 'grow' or 'shrink' or 'add': 6
                        
      *************     
    *****************   
  ********************* 
 ***********************
 ***********************
 ***********************
 ***********************
 ***********************
  ********************* 
    *****************   
      *************     
Circle radius is now 6
Circle radius is now 6
radius or 'grow' or 'shrink' or 'add': add
Circle radius is now 6
radius or 'grow' or 'shrink' or 'add': ^C
That's all folks
$

There's also a tkinter version (which I wrote before the cli one). I think 
it's easier to read the complete code than the diff; so there, with some 
repetition:

$ cat mvc.py
#!/usr/bin/env python3
import tkinter as tk


class CircleModel:
    def __init__(self, radius):
        self._radius = radius
        self.views = []

    def add(self, view):
        self.views.append(view)

    def changed(self):
        for view in self.views:
            view.changed(self)

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, radius):
        if self._radius != radius:
            self._radius = radius
            self.changed()


class CircleView:
    def __init__(self, model):
        self._model = None
        self.model = model
        self.changed(model)

    @property
    def model(self):
        return self._model

    @model.setter
    def model(self, model):
        if self._model is not None:
            raise NotImplementedError
        model.add(self)
        self._model = model

    def changed(self, model):
        """React to model changes."""


class RadiusDeltaController:
    def __init__(self, model, delta):
        self.model = model
        self.delta = delta

    def grow(self):
        self.model.radius += self.delta

    def shrink(self):
        self.model.radius -= self.delta


class RadiusController:
    def __init__(self, model):
        self.model = model

    def set_value(self, value):
        self.model.radius = value


class CircleImageView(CircleView):
    def __init__(self, root, model, fill, **kw):
        self.canvas = tk.Canvas(root, width=100, height=100)
        self.fill = fill
        self.canvas.grid(**kw)
        self.id = None
        super().__init__(model)

    def changed(self, model):
        self.update_radius(model.radius)

    def update_radius(self, radius):
        id = self.id
        cx = cy = 50
        extent = cx-radius, cy-radius, cx+radius, cx+radius
        if id is None:
            self.id = self.canvas.create_oval(
                *extent, fill=self.fill)
        else:
            self.canvas.coords(id, *extent)


class ResizeView(CircleView):
    def __init__(self, root, model, controller, **kw):
        self.frame = tk.Frame(root)
        self.frame.grid()
        self.grow = tk.Button(
            self.frame, text="Grow", command=controller.grow)
        self.grow.pack(side=tk.LEFT)
        self.shrink = tk.Button(
            self.frame, text="Shrink", command=controller.shrink)
        self.shrink.pack(side=tk.LEFT)
        super().__init__(model)

    def changed(self, model):
        self.grow["text"] = "Grow to {}".format(model.radius + 10)
        self.shrink["text"] = "Shrink to {}".format(model.radius - 10)


class RadiusView(CircleView):
    def __init__(self, root, model, controller, **kw):
        self.controller = controller
        self.frame = tk.Frame(root)
        self.frame.grid(**kw)
        self.label = tk.Label(self.frame, text="Radius")
        self.label.grid(row=0, column=0)
        self.hint = tk.Label(self.frame, text="Hit <Return> to apply")
        self.hint.grid(row=0, column=3)
        self.textvariable = tk.StringVar()
        self.entry = tk.Entry(self.frame, textvariable=self.textvariable)
        self.entry.bind("<Key-Return>", self.set_value)
        self.entry.grid(row=0, column=1)
        super().__init__(model)

    def set_value(self, *args):
        try:
            radius = int(self.textvariable.get())
        except ValueError:
            pass
        else:
            self.controller.set_value(radius)

    def get_value(self, model):
        return str(model.radius)

    def changed(self, model):
        self.textvariable.set(self.get_value(model))


if __name__ == "__main__":
    root = tk.Tk()
    circle = CircleModel(42)
    red_view = CircleImageView(
        root, circle, "red",
        row=0, column=0)
    green_view = CircleImageView(
        root, circle, "green",
        row=0, column=1)
    resize_view = ResizeView(
        root, circle, RadiusDeltaController(circle, delta=10),
        row=1, column=0, columnspan=2)
    radius_view = RadiusView(
        root, circle, RadiusController(circle),
        row=2, column=0, columnspan=2)

    root.mainloop()
$


From steve at pearwood.info  Sun May 29 22:17:54 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 30 May 2016 12:17:54 +1000
Subject: [Tutor] Logging exceptions, but getting stderr output instead
In-Reply-To: <CA+Q8_JfvkgKKNhhxeCddFCD3+sXWr5YtLB=O2Th0SDdD2OKfSA@mail.gmail.com>
References: <CA+Q8_JfvkgKKNhhxeCddFCD3+sXWr5YtLB=O2Th0SDdD2OKfSA@mail.gmail.com>
Message-ID: <20160530021754.GM12028@ando.pearwood.info>

On Wed, May 25, 2016 at 02:11:01PM -0400, Alex Hall wrote:

> As a quick aside, is there an easy way to halt script execution for some
> exceptions? Right now, catching them means that execution continues, but I
> sometimes want to log the problem and then abort the script, as the error
> means it shouldn't continue. Thanks.

In general you shouldn't fill your code with exception handling code if 
you can avoid it. You should only catch exceptions that you can handle and 
recover from. It's okay to log them right there, but since it's a 
recoverable error it should be a warning, not an error.

You should generally not catch fatal errors (except once, see below). If 
you must catch them, to decide whether or not they are fatal, then don't 
log them at the point you caught it, just re-raise using the base 
"raise" statement.

Finally, you should wrap your entire script in a single try...except to 
catch all the fatal exceptions in one go, log them, and exit. One way is 
this:


# Run the main script.
if __name__ == '__main__':
    try:
        main()
    except Exception:
        logging.exception("message")
        sys.exit(error_code)


which will log an Error with "message", and the details of the exception 
including the traceback before exiting.

An alternative to a try...except block will be to set the excepthook 
before running main().

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

As always, it's okay to break these rules carefully and after giving 
them due thought. But if you find yourself calling sys.exit dozens of 
times from wildly-separate parts of your code, you're probably doing it 
wrong.


-- 
Steve

From steve at pearwood.info  Sun May 29 22:33:06 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Mon, 30 May 2016 12:33:06 +1000
Subject: [Tutor] Logging exceptions, but getting stderr output instead
In-Reply-To: <CA+Q8_Jf+H3QA+cMbnMqBNsNFwjeqSYwrv5jv=HROUV7-a_iOSA@mail.gmail.com>
References: <CA+Q8_JfvkgKKNhhxeCddFCD3+sXWr5YtLB=O2Th0SDdD2OKfSA@mail.gmail.com>
 <ni4utu$svv$1@ger.gmane.org>
 <CA+Q8_Jf+H3QA+cMbnMqBNsNFwjeqSYwrv5jv=HROUV7-a_iOSA@mail.gmail.com>
Message-ID: <20160530023306.GN12028@ando.pearwood.info>

On Wed, May 25, 2016 at 03:44:28PM -0400, Alex Hall wrote:
> You're not missing anything; I wasn't clear. I wasn't sure if raise or
> sys.exit(1) were the preferred ways, or if there was some other way I
> didn't know about. I've never had to force a script to halt before, at
> least not one I mean to schedule to run on its own once a day, so wanted to
> check that those are indeed the recommended ways.

raise and sys.exit() do different things, which both happen to result in 
the script halting.

`raise` re-raises the current exception, that's all. What happens from 
that point depends: the exception could be caught by another 
try...except handler, or it might not be. If it isn't caught by 
anything, the interpreter will print a traceback and error message, and 
then halt with a non-zero exit code.

`sys.exit` will exit. Technically it actually raises an exception, 
SystemExit, which can also be caught like any other exception, but 
normally it won't be. (I can go into detail about exactly when it 
will be caught if you like.) If you call sys.exit with no argument, or 
with argument 0, then it will halt the script with exit code 0 
("success") and no traceback. Any other integer code will set the exit 
code to that value, and any string value will print that string to 
stderr and then exit with a non-zero exit code.


-- 
Steve

From an at linux.com  Mon May 30 05:23:58 2016
From: an at linux.com (An Nguyen)
Date: Mon, 30 May 2016 16:23:58 +0700
Subject: [Tutor] Adding tasks periodically to
 asyncio.get_event_loop().run_forever()
Message-ID: <CANa5jNQSwMtgLj-XOh7FYK2QHtSsswfTdegd=U1Y8TnBgfBRdg@mail.gmail.com>

Hello all,

I have a question related to AsyncIO. I have a while True: loop that
executes a list of tasks asynchronously every 10 seconds.

while True:
>     loop = asyncio.get_event_loop()
>     tasks = [ ]
>     for arg in args:
>         tasks.append(asyncio.ensure_future(my_coroutine(arg)))
>     results = [ ]
>     results = loop.run_until_complete(gather(*tasks))
>     print(results)
>     sleep(10)
>


Now how can I achieve the same outcome with loop.run_forever()?

What I want to achieve is to have a loop.run_forever() in my main(). Then
periodically, a list of tasks will be added to that event_loop for
execution.

Please enlighten me.

Thank you.
An.

From steve.lett777 at gmail.com  Mon May 30 01:45:21 2016
From: steve.lett777 at gmail.com (Steve Lett)
Date: Mon, 30 May 2016 15:45:21 +1000
Subject: [Tutor] Study Tips
Message-ID: <CABg+j4sb=hvALbFVTMpQG=eSmDKzD=E+vKmtCb368wyPPXV2aw@mail.gmail.com>

Hi folks,
Just started learning python. I've been having a really hard time in
getting started, and still am! I have a slight learning difficulty,
including a stroke in Jan.2010. You wouldnt know even if u were here
looking at me! Praise God for the great salvation!
I have a slight learning difficulty. Has anyone got any tips on how to
study programming and what approach would be best for me?

Out of a long list of books that I have collected ( python, Blender, etc )
I have decided to start on Introducing Python (hard copy 2nd Ed, ebook 3rd
ed) by Bill Lubanovic. Before that I was going to start with Python
Programming for the Absolute Beginner, Michael Dawson.

Any thoughts on these issues and especially the study tips already
mentioned.

Thank you, Steve

From alan.gauld at yahoo.co.uk  Mon May 30 12:30:07 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 30 May 2016 17:30:07 +0100
Subject: [Tutor] Correct use of model-view-controller design pattern
In-Reply-To: <CANDiX9JqTD+Pwhd2n0ivGF=HNAf4vy1M6Y60dN97PAFrV9nQjA@mail.gmail.com>
References: <CANDiX9JqTD+Pwhd2n0ivGF=HNAf4vy1M6Y60dN97PAFrV9nQjA@mail.gmail.com>
Message-ID: <nihpqf$svc$1@ger.gmane.org>

On 29/05/16 05:33, boB Stepp wrote:

As promised I'm back so will try to answer these...

> Some other questions:
> 
> 1)  If I were to add code to filter user inputs, which file is the
> logical place to place such code?  My current impression is that it
> should go in the controller, but I could see it being in the view.
> However, if I were to write a Validation class, I could see that as
> having uses beyond checking just user input.

Filtering user input is one type of validation (others include
type and value checking) Usually the view (especially in a GUI)
will control the type checking and in  some cases the value
checking too (think calendar pickers). But the controller may
also do some data adjustment (such as reformatting a date
to suit a particular model). But mostly I expect the view
to collect the correct data in terms of primitive type/value.

An example where more complex validation might be required is
where you want to validate a credit card or an account number.
In that case the controller may call a business service before
passing the validated details onto the appropriate model(s)
to process.

Models should usually expect to be given good data. In some
cases you might want to do a belt n' braces data check in
the model too, but mostly you assume your front end is
catching the bad stuff (see file processing below).

> 2)  Currently I am using a while loop in the controller to keep the
> view 'alive'.  If I were to convert the view to a tkinter GUI, where
> would the root.mainloop() statement go?  In the controller's main()
> method?  What GUI-related stumbling blocks might I easily run into in
> going from CLI to GUI with this existing code?

See previous post. The main loop is almost always in the view.

> 3)  If I were to add data files in place of (or in addition to) user
> input, in which aspect of MVC would file I/O be handled?

This is where things get interesting. When processing files the
view/controller are only likely to be validating the filename and
initiating the process. This means that there needs to be a model object
somewhere that processes the file. But the content of the
file is unsafe  so that model needs to do all the data
validation that would normally be done in the view/controller.

Its not unusual to have a dedicated model for such batch processing
and it will then call the other model methods for each record processed,
effectively becoming a controller of sorts. There may
be opportunities for code reuse between the UI controller and
the batch controller.

> BTW, I did not attempt to write any classes as things seemed simple
> enough that functions seemed more appropriate and straightforward to
> me.  If that is a bad choice, please let me know!

At this level of simplicity its hard to see the advantages of the MVC
paradigm. (A bit like OOP itself!) Its only when things start to get
complicated that MVC starts to simplify things rather than add noise.


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



From dirkjsoren at gmail.com  Mon May 30 13:21:49 2016
From: dirkjsoren at gmail.com (DirkJSoren@gmail.com)
Date: Mon, 30 May 2016 11:21:49 -0600
Subject: [Tutor] Learning Regular Expressions
In-Reply-To: <ni2b6l$a9j$1@ger.gmane.org>
References: <57437F6D.9010808@gmail.com> <ni2b6l$a9j$1@ger.gmane.org>
Message-ID: <574C76AD.6020209@gmail.com>

On 05/24/2016 01:48 PM, Alan Gauld via Tutor wrote:
> On 23/05/16 23:08, Terry--gmail wrote:
>
>> scripted worked great without the notes!  I'd like to know what it is in
>> the below Tripple-Quoted section that is causing me this problem...if
>> anyone recognizes. In IDLE's script file..._it's all colored green_,
>> which I thought meant Python was going to ignore everything between the
>> tripple-quotes!
> Its all green forv me too and it runs perfectly - as in it does
> absolutly nothing.
>
>
> And if I add print('hello world') at the end it prionts ok too.
>
> I even tried assigning your docsstring to a variable and printing
> that and it too worked.
>
> Linux Mint 17
> Python 3.4.3
> IDLE 3
>
> So I don't think this is your entire problem. Maybe you should
> show us some code that actually causes the error?
>
>> But if I run just the below portion of the script in
>> it's own file, I get the same While Scanning Tripple-Quotes error.
> As above, it runs silently for me.
>
Hi Alan,

I moved my notes that contained any '\'s to a different python file.
However, if we run it, we get the error I was having. Here's the
script:

#!/usr/bin/env python3

'''
Regular Expressions - or at least some

Identifiers:

\d  any number
\D  anything but a number (digit)
\s  space
\S  anything but a space
\w  any character
\W  anything but a character
.   any character (or even a period itself if you use \.) except for a 
newline
a   search for just the letter 'a'
\b  the white space around words

Modifiers
{x}    we are expecting "x" number of something
{1, 3}  we're expecting 1-3 in length of something -, so for digits we 
write  \d{1-3}
+  means Match 1 or more
?  means Match 0 or 1
*   Match 0 or more
$  Match the end of a string
^  Match the beginning of a string
|   Match either or   - so you might write  \d{1-3} | \w{5-6}
[ ]  a range or "variance" such as [A-Z] or [A-Za-z] Cap 1st letter 
followed by lower case
             or [1-5a-qA-Z] starts with a number inclusive of 1-5 then 
lower case letter then
             followed by any Cap letter! :)

White Space Characters  (may not be seen):
\n  new line
\s  space
\t   tab
\e  escape
\f  form feed
\r  return

DON'T FORGET!:
.  +  *  ?  [  ]  $  ^  (  )  {  }  |  \   if you really want to use 
these, you must escape them '\'

'''



From robertvstepp at gmail.com  Mon May 30 15:02:42 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 30 May 2016 14:02:42 -0500
Subject: [Tutor] Study Tips
In-Reply-To: <CABg+j4sb=hvALbFVTMpQG=eSmDKzD=E+vKmtCb368wyPPXV2aw@mail.gmail.com>
References: <CABg+j4sb=hvALbFVTMpQG=eSmDKzD=E+vKmtCb368wyPPXV2aw@mail.gmail.com>
Message-ID: <CANDiX9+Yw-b7F=p=XosuNpaV7rc_orWkg2Gs4CZsE+FUFtxctQ@mail.gmail.com>

Hi and welcome to Tutor, Steve!  I am one of the learners, and I can
honestly say that you have found the right place to ask questions when
you get stuck.  Things on the list seem slow this weekend.  In the US,
where I am at, we are having Memorial Day weekend.  I still have to
chew over two meaty answers to questions I asked this weekend from two
resident Pythonistas, Peter Otten and Alan Gauld (Who is also one of
the list's moderators.), but I can't quite get out of holiday mode!
As a way out of learning about decorators, particularly property ones
(Which Peter used in his illustrative code.), I now will post a
lengthy response to your question(s), including some general stuff you
were not asking about that I think you might find helpful.

On Mon, May 30, 2016 at 12:45 AM, Steve Lett <steve.lett777 at gmail.com> wrote:

> I have a slight learning difficulty. Has anyone got any tips on how to
> study programming and what approach would be best for me?

First, I would like to mention some things I have observed that tend
to trip up newcomers to programming and especially in using this
mailing list.  When you successfully subscribed to Tutor, you should
have received a welcome email which attempted to explain some of the
rules this list follows.  If I recall correctly, it even contains a
link to a web page that explains how to ask intelligent questions on
technical mailing lists (Like this one.).  If you vary from this
practice, then you will probably be given that link again
(http://sscce.org/).  If you have not read it, please do.  It is quite
helpful, not just for you, but for those who *do* wish to help you.

For instance, I trimmed your post down to what I am going to try to
respond to, but I fear I may run on a bit.

The most basic thing is to always respond to the whole Tutor list, not
just to the person who posts a response to your email.  Tutor is a
collaborative learning environment.  Answers to your questions could
easily prove helpful to me and others.  Also, by posting to the entire
Tutor list, you ensure to get a variety of perspectives on your
issue(s).

I notice you have a Gmail address.  If you are using the Gmail email
program, too, then you need to make sure that ALL of your emails and
responses to Tutor are in plain text with no attachments.  If you
don't do this, you will have problems.  The main technical one is that
Python's structure is dependent on consistent and proper indentation
(Four spaces per indent preferred.).  If that indentation gets altered
by using rich text, html formatting, etc., which this list does not
use, then people will not be able to copy and paste your code as is.
The Gmail email program will not do plain text automatically for you,
so if you do not know how to ensure this, then you have some Googling
to do!  If you want to see what your just sent email looks like to the
list members, point your browser to either

https://mail.python.org/pipermail/tutor/

or,

https://www.mail-archive.com/tutor at python.org/

and find your email and view it.  Looks like you are doing fine so
far.  Note:  The first link will have your email show up very quickly.
The second often seems to have a noticeable lag before it shows up.

Also, make sure when you have a problem with one of your programs that
you do the following:

1)  Usually state your operating system (OS) and version of Python
being used.  As you appear to be newly learning both programming and
Python I highly recommend you start with Python 3, which is now the
only version of Python being actively developed.  Python 2 is still
heavily in use, but now is in maintenance mode and will eventually no
longer get even new bug fixes.  The two books you mentioned both use
Python 3, so I suspect you have already realized this.

2)  COPY and PASTE the code you are having issues with.  Do NOT try to
hand-type your code in.  You will probably make a typo along the way,
producing code in your email that is NOT the code you actually ran and
inevitably introducing new errors in that hand-copied code which have
nothing to do with your original problem.  Another Gmail warning:  I
have found that when I copy something from the Python interpreter and
attempt to paste it into an email, my indentations vanish!  This means
I have to go carefully through my code and ensure that all of the
indents are recreated.  Eventually I will have to switch email
clients, but I have many things tied to making Google's environment
work (Android Nexus 5 phone, calendars, etc.) that I dread having to
figure out how to stitch together a variety of programs to recreate my
currently seamless digital experience.).

[An aside:  There are two ways to run Python code, in the Python
interactive interpreter and by invoking Python (Often from the command
line.) on a file containing valid Python code.  The first is handy to
experiment in as you get immediate feedback.  The latter is the form
your applications will be done in.  Python supplies IDLE, which
functions as both an interactive Python environment and as a Python
code editor/integrated development environment (IDE).  Any book or
beginner's tutorial you use should have a section on how to use the
two modes of IDLE.  And of course if you are already using a
programmer's text editor you like, you can use that instead.]

3)  COPY and PASTE the FULL TRACEBACK (That is, the error report
Python gives you.) that is generated from running the code you are
struggling with.  The Pythonistas can deduce amazing things just from
that traceback!  A tip:  Read the traceback from the bottom up.  Note
the line number(s) it points to.  Better tip:  Copy the error message
and paste it into a search engine--you will more often than not solve
your own problem by doing this bit of research.

Do not top post!  Instead interleave your comments.  If you do not
know what this means have a look at

https://en.wikipedia.org/wiki/Posting_style

For instance, if had top posted my responses to your email, you would
have seen all of this I am writing at the beginning of this email, but
your (trimmed) email that I would be responding to would be at the
bottom.  If I had top posted, the context that I am responding to
would be at the bottom in an awkward location to locate, especially
when someone runs on and on like I am now doing. ~(:>)

Three things that can help you solve many of your own problems:

1)  Study the code you are having problems with and try to rewrite it
in a much shorter and simpler form that accurately reproduces the
problem(s).  If you can distill your code down to a handful (Or less!)
lines that accurately reproduce the problem, then you will often see
the problem and solution yourself without having to ask anyone
questions!

2)  Search online for helpful information.  I have already alluded to
this above when I mentioned copying and pasting your traceback into a
search engine.  It is highly likely that others have had your very
same issues and found their answers.  Also, this shows people that you
are willing to work for your supper and are actually trying hard to
learn and do not wish to be spoon-fed.

3)  print() is your dearest of dearest friends!  When you do not know
what is going wrong, intersperse your code with print() calls in the
most likely trouble spots.  Print out those variables and see what is
really being referenced.

Now on to your *actual* questions:

>
> Out of a long list of books that I have collected ( python, Blender, etc )
> I have decided to start on Introducing Python (hard copy 2nd Ed, ebook 3rd
> ed) by Bill Lubanovic. Before that I was going to start with Python
> Programming for the Absolute Beginner, Michael Dawson.

I own "Introducing Python".  It came out a couple of years ago.  I am
pretty sure it is still only in its original edition.  OTH, the other
book by Dawson is in its third edition.  Are you sure you did not get
editions mixed up?  But that is not important.

You sound like me in that you like books.  I buy too many of them and
worse, do not read most of them.  So I think that you need to find a
book which goes at a pace you are comfortable with, talks geek-speak
at a level that is understandable, and that is interesting enough that
you are likely to study it from cover to cover.  Also, it needs to
have plenty of useful exercises/problems.  The real learning occurs
when you write and debug your own code.  A good book will have
suggested exercises that are challenging at the right level and
targeted to the concepts being taught at that moment.  Only you can
decide if a book is a good fit for you or not.

Are you totally new to programming in *any* language?  If yes, you
have much more to learn than *just* a programming language.  I am
going to assume that you are very new to programming in general.
Forgive me if I am mistaken!  But if you are, then some of the things
you must learn that are language-independent:

1)  You must have the ability to focus on the tiniest of details.
Programming languages care about every jot and tittle.  Whether a
letter is upper or lower case matters in most languages (Especially
Python.).  Spaces matter! (Especially in Python!!)  You will find that
most of your mistakes that cause you tremendous grief are because of
the tiniest, most insignificant typos, or similar errors.  I once
spent hours trying to make a segment of copied and pasted code work.
I just could not see anything wrong!  I eventually realized that the
quotes being used in the copied code were of two types:  those that
pointed slightly to the right and those that were pointed slightly to
the left.  But the font my system displayed these in made these
differences invisible to me.  It was only after I looked at the
characters' underlying display code that I discovered that they were
in fact two distinct characters!

2)  Programming is all about solving problems, no matter the language.
And you have to be able to express your solutions to those problems in
a sequence of very detailed, very concrete steps as if you were
talking to a very stupid person for whom *everything* has to be
spelled out in great detail.  I believe that your enjoyment and
success in programming will depend on your ultimate comfort level
here.  But if you relish the challenge of problem solving and feel a
huge rush of pleasure after having solved a particularly gnarly
problem, then Python and programming is definitely for you!  Plus the
creative aspect of fashioning something special out of nothing other
than the underlying ones and zeroes provides great satisfaction as
well.

3)  You will need a great deal of patience (and imagination!).
Getting everything just right so the very stupid computer will
ultimately bend to your unyielding will requires patience (and
imagination) in abundance.

4)  You have to learn algorithmic thinking, which is what much of
point (2) is about.  If this is foreign to you, then whatever book you
choose needs to teach you this.

And there are others.  You have to develop a programmer's way of
thinking and you need to learn and acquire these thinking skills.

So on these lines I do not think I can recommend "Introducing Python"
for you.  Despite claiming to be suitable for a newcomer to
programming, it is fairly fast paced and tries to go through a lot of
language details quickly.  And the level of geek-speak stays on the
fairly technical side.

Dawson's book is a fairly gentle introduction that I think you can
follow.  The problems with it will come when you try to get into the
game programming where he uses the livewires package.  Underlying this
package is PyGame.  People who have posted on this list have had
issues with installing, configuring, and using both of these.  If you
continue with the sequel to Dawson's book, which is written by a
different author, that sequel uses PyGame only.  The problem is that
these two books are using versions of livewires and pygame that won't
work as is with the most current version of Python 3, so you will have
some work to do to get your gaming packages these books use to work.

I myself recently read through the part one to "Python Crash Course"
by Eric Matthes that came out about a year ago.  He divides his book
up into two halves.  Part one is "The Basics" while part two is
composed of "Projects".  I think you might like this book, too.  It is
faster paced than Dawson's book, but not nearly so as Lubanovic's.  It
does not try to exhaustively cover Python's language features, but it
does cover the bread-and-butter ones rather well for a newbie's
perspective.  Matthes is a high school teacher, and I think he is
targeting that sort of level in his presentation based on his teaching
experience.  I think that you could use this book along with Dawson's,
delving into the latter when you need something broken down into a
more detailed explanation.  And then there are the projects you can
try out!  I did not go through those, though I probably should have.
But I have so many projects of my own going on that I have more than
enough to do.

There are a ton of good books and tutorials online.  Search for them.
Search the Tutor archives.  As you might imagine, your questions have
been asked often before.  Alan Gauld has an online tutorial that has a
link to it in any of his posts to Tutor.  He also has recently
released a book himself for learning Python centered around a projects
approach.

I have done way to much typing.  I hope that some of it might prove useful.

Good luck and have at it!

boB



-- 
boB

From robertvstepp at gmail.com  Mon May 30 15:48:44 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 30 May 2016 14:48:44 -0500
Subject: [Tutor] Learning Regular Expressions
In-Reply-To: <574C74A8.1040700@gmail.com>
References: <57437F6D.9010808@gmail.com>
 <CANDiX9Ky71MCtRKmFP_yXnaU+WP=pq5cV3vAKABa8fhpjjqB=A@mail.gmail.com>
 <574C74A8.1040700@gmail.com>
Message-ID: <CANDiX9LZxprig1pwaspXB_xP7TUPPa5fsnLB9D8O8uXwZkfg0w@mail.gmail.com>

On Mon, May 30, 2016 at 12:13 PM, DirkJSoren at gmail.com
<dirkjsoren at gmail.com> wrote:
> Hi bob,
>
> I had used the wrong email address when I wrote to python tutor on this, and
> evidently it
> took a while for the monitors to let it go ahead and be entered in the list,
> so I apologize
> for the delay in my reply.

That's okay.  Note that Tutor is a collaborative learning environment,
so that normally you should send your responses to the whole list, not
just me.  That way we can all learn from what is written.  So I am
sending this to the Tutor list, but not everything as I notice you
sent another response with pretty much everything to Alan and Tutor.

> I continued to mess with it, and it seems or appears that escape '\' was
> being noticed by
> the interpreter despite the fact it is in a triple quoted area!
>
> As for the traceback, (I am not sure what you mean by 'FULL TRACEBACK'),
> there was no
> highlighted point in the program. I simply got the message I printed here.

I am back at home now with access to Python 3.  What I meant was, if I
have this Python file, test_traceback.py:

#!/usr/bin/env python3

print('''I will deliberately use a backslash inside this triple-quote.\''')

When I run this code from the command line, I get:

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Windows\system32>e:

E:\>cd /py_projects

E:\py_projects>py test_traceback.py
  File "test_traceback.py", line 5

    ^
SyntaxError: EOF while scanning triple-quoted string literal

This is what I mean by a full traceback.  Notice it tells me what line
of my code file where it first encountered a problem.  Just so you
have it in mind, with things involving quotes issues, the actual point
of error might be several lines earlier.  But in this case I kept
things simple to illustrate the point.

Now if you ran my one-line program in the Python interpreter, you
would get a different kind of problem:

Python 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:54:25) [MSC v.1900
64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
py3: print('''I will deliberately use a backslash inside this triple-quote.\''')
...
...
...
...
...

Notice that every time I hit return in the interpreter, trying to
*run* the code, it would not do so.  Instead, every time I press
<Enter> I get three dots.  This is because in my actual code it sees
the second triple-quote as being two single-quotes and a parenthesis.
It does not see the triple-quote as yet being completed, and,
additionally, it does not see the print function as being closed.  So
if I do these completions, I get:

py3: print('''I will deliberately use a backslash inside this triple-quote.\''')
...
...
...
...
... '
...
...
... '''
... )
I will deliberately use a backslash inside this triple-quote.''')




'



py3:

Notice the extra single-quote I threw in.  I hope it shows in more
detail what is going on.

HTH!

boB

From alan.gauld at yahoo.co.uk  Mon May 30 17:07:59 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 30 May 2016 22:07:59 +0100
Subject: [Tutor] Learning Regular Expressions
In-Reply-To: <574C76AD.6020209@gmail.com>
References: <57437F6D.9010808@gmail.com> <ni2b6l$a9j$1@ger.gmane.org>
 <574C76AD.6020209@gmail.com>
Message-ID: <niia3f$l1p$1@ger.gmane.org>

On 30/05/16 18:21, DirkJSoren at gmail.com wrote:

> I moved my notes that contained any '\'s to a different python file.
> However, if we run it, we get the error I was having. Here's the
> script:

Runs fine for me.

Can you run it using the python command line interpreter rather
than IDLE? Do you still get errors? If so cut n paste the full
error to the list.


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



From dirkjsoren at gmail.com  Mon May 30 17:13:57 2016
From: dirkjsoren at gmail.com (DirkJSoren@gmail.com)
Date: Mon, 30 May 2016 15:13:57 -0600
Subject: [Tutor] Learning Regular Expressions
In-Reply-To: <ni2b6l$a9j$1@ger.gmane.org>
References: <57437F6D.9010808@gmail.com> <ni2b6l$a9j$1@ger.gmane.org>
Message-ID: <574CAD15.7070207@gmail.com>

Thanks Bob,





OK. The escape character \ still is active in escaping the next 
character or space when inside of triple quotes. So, I guess when the 
program is running, since I am not printing these things out, I don't 
care if anything in my notes is escaped unless it is a strategic single 
or double quote....thus disrupting the bubble of the comment formed by 
such triple quotes.

Speaking of single and double quotes, I noticed that I had used two 
single ' to surround some things, so I changed them to double quotes so 
as not to confuse my triple quotes. Then I noticed that I had also used 
contractions with ' apostrophes which would also mess up my comment 
bubble, so I got rid of those also. As far as I can tell, the triple 
single quotes (''') should work at that point. In fact, they do if I 
wrap this whole section in a print( ) statement and paste it into IDLE 
SHELL. But! I found as soon as I had IDLE run my script I got the same 
error.

Here is where I am at now with this script:   (NOTE:  I have the final 
solution below this listing.)

#!/usr/bin/env python3

'''
Regular Expressions - or at least some

Identifiers:

\d  any number
\D  anything but a number (digit)
\s  space
\S  anything but a space
\w  any character
\W  anything but a character
\.   any character (or even a period itself if you use \.) except for a 
newline
\a   search for just the letter "a"
\b  the white space around words

Modifiers
{x}    we are expecting "x" number of something
{1, 3}  we are expecting 1-3 in length of something -, so for digits we 
write  \d{1-3}
+  means Match 1 or more
?  means Match 0 or 1
*   Match 0 or more
$  Match the end of a string
^  Match the beginning of a string
|   Match either or   - so you might write  \d{1-3} | \w{5-6}
[ ]  a range or "variance" such as [A-Z] or [A-Za-z] Cap 1st letter 
followed by lower case
             or [1-5a-qA-Z] starts with a number inclusive of 1-5 then 
lower case letter then
             followed by any Cap letter! :)

White Space Characters  (may not be seen):
\n  new line
\s  space
\t   tab
\e  escape
\f  form feed
\r  return

DO NOT FORGET!:
.  +  *  ?  [  ]  $  ^  (  )  {  }  |  \    if you really want to use 
these, you must escape them

'''

I was not getting a line number for the error because I was running it 
only from IDLE and I was looking only at the commented area...as that 
now was the only thing left in the script....or was it? It hadn't 
occurred to me to try the linux command line.  When I called it from the 
Linux Console, I got:

[justme at ispy] ~/python_work$ python3 RE-1.py
   File "RE-1.py", line 69

     ^
SyntaxError: EOF while scanning triple-quoted string literal
[justme at ispy] ~/python_work$

Which puzzled me, as I didn't have 69 lines!  And guess what I found 
when I scrolled down past the end of my script? Way down out of sight 
below my program was  a single  ''' setting down there all by it's 
lonesome self!  -a fragment of me changing things all over the place 
trying to figure out what was going wrong....it had slipped below my 
line of sight and with further chances continued to work it's way down 
the page.

I think all these fixes...this solves my problem!  Thanks for your time 
and help!  :)


From alan.gauld at yahoo.co.uk  Mon May 30 17:11:08 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Mon, 30 May 2016 22:11:08 +0100
Subject: [Tutor] Study Tips
In-Reply-To: <CABg+j4sb=hvALbFVTMpQG=eSmDKzD=E+vKmtCb368wyPPXV2aw@mail.gmail.com>
References: <CABg+j4sb=hvALbFVTMpQG=eSmDKzD=E+vKmtCb368wyPPXV2aw@mail.gmail.com>
Message-ID: <niia9c$q81$1@ger.gmane.org>

On 30/05/16 06:45, Steve Lett wrote:

> Out of a long list of books that I have collected ( python, Blender, etc )
> I have decided to start on Introducing Python (hard copy 2nd Ed, ebook 3rd
> ed) by Bill Lubanovic. Before that I was going to start with Python
> Programming for the Absolute Beginner, Michael Dawson.

Bob has mentioned many useful bits of advice.

I'd just emphasise one thing:

write code., lots of it.

Don't just settle for the examples/exercises in your book.
Use them as a start but extend them. Add extra features.
Change the output format or the sort order.
Combine examples to make bigger programs.

Writing code means making mistakes and, in finding the solution,
you learn far more than from just reading code.

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



From david.rock at gmail.com  Mon May 30 19:07:57 2016
From: david.rock at gmail.com (David Rock)
Date: Mon, 30 May 2016 18:07:57 -0500
Subject: [Tutor] Study Tips
In-Reply-To: <niia9c$q81$1@ger.gmane.org>
References: <CABg+j4sb=hvALbFVTMpQG=eSmDKzD=E+vKmtCb368wyPPXV2aw@mail.gmail.com>
 <niia9c$q81$1@ger.gmane.org>
Message-ID: <20160530230757.GF22214@raspberrypi>

* Alan Gauld via Tutor <tutor at python.org> [2016-05-30 22:11]:
> On 30/05/16 06:45, Steve Lett wrote:
> 
> write code., lots of it.
> 
> Don't just settle for the examples/exercises in your book.
> Use them as a start but extend them. Add extra features.
> Change the output format or the sort order.
> Combine examples to make bigger programs.
> 
> Writing code means making mistakes and, in finding the solution,
> you learn far more than from just reading code.

And a corollary to this: have a purpose for why you are writing it.

Learning code for the sake of learning it will get old quickly.  You will get a
lot further if you are trying to solve a problem that you care about.  Think of
something you would like to automate, or calculate, or process.  Do you have
data you would like to analyze? As you learn different elements and apply them
to a practical use that does something for you, it will be more satisfying and
more likely to stick in your brain.

-- 
David Rock
david at graniteweb.com

From akleider at sonic.net  Mon May 30 19:37:24 2016
From: akleider at sonic.net (Alex Kleider)
Date: Mon, 30 May 2016 16:37:24 -0700
Subject: [Tutor] Study Tips
In-Reply-To: <CANDiX9+Yw-b7F=p=XosuNpaV7rc_orWkg2Gs4CZsE+FUFtxctQ@mail.gmail.com>
References: <CABg+j4sb=hvALbFVTMpQG=eSmDKzD=E+vKmtCb368wyPPXV2aw@mail.gmail.com>
 <CANDiX9+Yw-b7F=p=XosuNpaV7rc_orWkg2Gs4CZsE+FUFtxctQ@mail.gmail.com>
Message-ID: <aa307d8ae6428544b260fa3ed29202ac@sonic.net>


On 2016-05-30 12:02, boB Stepp wrote:
...
> Are you totally new to programming in *any* language?  If yes, you
> have much more to learn than *just* a programming language.  I am
> going to assume that you are very new to programming in general.
> Forgive me if I am mistaken!  But if you are, then some of the things
> you must learn that are language-independent:
> 

With the above comments in mind, this might be worth looking at:
http://openbookproject.net/thinkcs/python/english3e/

I cut my teeth on the original version which was Python 2.7 based and
was just the thing meeting the criteria mentioned by Bob.
I assume the Python 3 version has the same merits.
Best wishes,
Alex


From colbychristensen at hotmail.com  Mon May 30 19:12:29 2016
From: colbychristensen at hotmail.com (Colby Christensen)
Date: Mon, 30 May 2016 19:12:29 -0400
Subject: [Tutor] Study Tips
In-Reply-To: <20160530230757.GF22214@raspberrypi>
References: <CABg+j4sb=hvALbFVTMpQG=eSmDKzD=E+vKmtCb368wyPPXV2aw@mail.gmail.com>,
 <niia9c$q81$1@ger.gmane.org>, <20160530230757.GF22214@raspberrypi>
Message-ID: <COL129-W87286A5ACDFC4B6C0D7EACD0450@phx.gbl>

I completely agree with what's been said. I also have used online learning sites like Coursera, Udacity and Lynda. There's something about being able see, hear and do that clicks for me.
Good Luck
Colby

> From: david.rock at gmail.com
> Date: Mon, 30 May 2016 18:07:57 -0500
> To: tutor at python.org
> Subject: Re: [Tutor] Study Tips
> 
> * Alan Gauld via Tutor  [2016-05-30 22:11]:
>> On 30/05/16 06:45, Steve Lett wrote:
>> 
>> write code., lots of it.
>> 
>> Don't just settle for the examples/exercises in your book.
>> Use them as a start but extend them. Add extra features.
>> Change the output format or the sort order.
>> Combine examples to make bigger programs.
>> 
>> Writing code means making mistakes and, in finding the solution,
>> you learn far more than from just reading code.
> 
> And a corollary to this: have a purpose for why you are writing it.
> 
> Learning code for the sake of learning it will get old quickly. You will get a
> lot further if you are trying to solve a problem that you care about. Think of
> something you would like to automate, or calculate, or process. Do you have
> data you would like to analyze? As you learn different elements and apply them
> to a practical use that does something for you, it will be more satisfying and
> more likely to stick in your brain.
> 
> -- 
> David Rock
> david at graniteweb.com
> _______________________________________________
> Tutor maillist - Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
 		 	   		  

From steve.lett777 at gmail.com  Mon May 30 18:52:43 2016
From: steve.lett777 at gmail.com (Steve Lett)
Date: Tue, 31 May 2016 08:52:43 +1000
Subject: [Tutor] Study Tips
In-Reply-To: <CABg+j4sb=hvALbFVTMpQG=eSmDKzD=E+vKmtCb368wyPPXV2aw@mail.gmail.com>
References: <CABg+j4sb=hvALbFVTMpQG=eSmDKzD=E+vKmtCb368wyPPXV2aw@mail.gmail.com>
Message-ID: <CABg+j4uxb7dcMM2e8gcSOCADczaHYdSRWHWcfiLfo8Ud336m0Q@mail.gmail.com>

Thank you for the reply.
On 30/05/2016 3:45 PM, "Steve Lett" <steve.lett777 at gmail.com> wrote:

> Hi folks,
> Just started learning python. I've been having a really hard time in
> getting started, and still am! I have a slight learning difficulty,
> including a stroke in Jan.2010. You wouldnt know even if u were here
> looking at me! Praise God for the great salvation!
> I have a slight learning difficulty. Has anyone got any tips on how to
> study programming and what approach would be best for me?
>
> Out of a long list of books that I have collected ( python, Blender, etc )
> I have decided to start on Introducing Python (hard copy 2nd Ed, ebook 3rd
> ed) by Bill Lubanovic. Before that I was going to start with Python
> Programming for the Absolute Beginner, Michael Dawson.
>
> Any thoughts on these issues and especially the study tips already
> mentioned.
>
> Thank you, Steve
>

From terry.kemmerer at gmail.com  Mon May 30 17:21:13 2016
From: terry.kemmerer at gmail.com (Terry--gmail)
Date: Mon, 30 May 2016 15:21:13 -0600
Subject: [Tutor] Learning Regular Expressions
In-Reply-To: <niia3f$l1p$1@ger.gmane.org>
References: <57437F6D.9010808@gmail.com> <ni2b6l$a9j$1@ger.gmane.org>
 <574C76AD.6020209@gmail.com> <niia3f$l1p$1@ger.gmane.org>
Message-ID: <574CAEC9.5030000@gmail.com>

Thanks Alan

I noticed that I was using some double ' to encircle some things and 
some single ' for apostrophes in contractions....and fixed those...but 
apparently since you could run it, that part didn't matter. The problem 
was ultimately caused by a stray ''' which was a fragment of me messing 
with things trying to fix them and it slipped down my screen and was 
hidden from me when I would look at the script!

Thanks for double checking me. :)


On 05/30/2016 03:07 PM, Alan Gauld via Tutor wrote:
> On 30/05/16 18:21, DirkJSoren at gmail.com wrote:
>
>> I moved my notes that contained any '\'s to a different python file.
>> However, if we run it, we get the error I was having. Here's the
>> script:
> Runs fine for me.
>
> Can you run it using the python command line interpreter rather
> than IDLE? Do you still get errors? If so cut n paste the full
> error to the list.
>
>


From robertvstepp at gmail.com  Mon May 30 20:50:26 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 30 May 2016 19:50:26 -0500
Subject: [Tutor] Correct use of model-view-controller design pattern
In-Reply-To: <niet9i$eqp$1@ger.gmane.org>
References: <CANDiX9JqTD+Pwhd2n0ivGF=HNAf4vy1M6Y60dN97PAFrV9nQjA@mail.gmail.com>
 <niet9i$eqp$1@ger.gmane.org>
Message-ID: <CANDiX9LfR9S=0GN+fw2C=-EMBz64YZYGGVdJzNuUvsU=pmOR_Q@mail.gmail.com>

On Sun, May 29, 2016 at 9:10 AM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 29/05/16 05:33, boB Stepp wrote:

>> My current understanding is that the model contains program logic and
>> the data which the program logic manipulates.
>
> Correct, all the core entities which make up the program are represented
> by models. Most things stored in a database will
> have a corresponding model.

Ah, the first major misconception I have.  Until now I have been
thinking more in terms of a single overarching model.  From what you
say here (and elsewhere in your response) one might have a Customer
class/model, account class/model, etc., all of which map to "things
stored in a database".  Later you mention lower-level models, that I
presume are classes with lower level abstraction, and I suppose there
are higher level models which provide higher levels of abstraction,
hiding these lower level models/classes.  I chose a procedural
approach for my coding examples as that both comes most naturally in
my current stage of development and seemed simplest.  But it is
looking like MVC is most useful for an OOP approach to things.

>> The controller ties things together, refreshing the view appropriately,
>> receiving messages from the view when something there has
>> been changed by the user, interrogating the model when needed,
>> and receiving the model's results and refreshing the view
>> appropriately.
>
> The controller is where the confusion starts. Every implementation of
> the MVC pattern seems to change the way the controller is defined. You
> are broadly correct but some frameworks have a more view focussed
> interpretation, others more model focused. For example some GUI
> frameworks combine the view and controller concepts into a single Window
> object (the Delphi/VB/MFC/OWL Windows GUI frameworks all
> take that approach). The JSP type 1 framework is similar in that
> the JSP page does both roles. But in the JSP type 2 framework the
> controller is separated out into a distinct entity.

This is what motivated to post my questions.  I wanted an explanation
of why I could not get consistent explanations of MVC from the
different sources I read.  As usual I am thinking about things too
rigidly.

> What everybody(?!) seems to agree on is that events generated by the
> view are forwarded to a controller(*) which determines whether a model
> needs to be involved and is so what method of which model needs to
> be invoked.
>
> (*)If the controller is embedded in the view object then that is
> probably handled by an internal  superclass method of the framework
> and based on an event table (similar to Tkinter's binding mechanism)
>
> The model responds, but how the view is notified varies. In some cases
> the views register with models and the model automatically sends
> notification messages to all registered views (by-passing the
> controller). In other cases the model si8mply sends a reply to the
> controller that invoked it and the controller decides which views should
> be updated.

So there can be multiple controllers, too?  And I suppose at different
levels of abstraction to match the correspondingly available models at
different levels of abstraction?

> In practice it's hard to separate the controller and view
> entirely (which is why some frameworks combine them) but
> it should definitely be possible to separate the models
> from the more UI elements. What the controller does do
> is allow you to swap different views within a single UI.
> For example a list view, versus a form view versus a
> graphical view, all of the same object or set of objects.

I was intuitively suspecting this.

> But I'd probably not make the controller the main() function.
> Instead I'd have a separate main that constructed the objects.
> The controller then has a handle_event() type method that
> receives the event from the UI view.
>
> So you make the view responsible for initiating the
> event processing not the controller. The controller
> then becomes a fairly simple validate-dispatch mechanism.

This makes more sense to me.  When I was trying to imagine writing a
tkinter GUI to be the UI I could not visualize how to make the view
totally decoupled from the controller code.  Along with what you said
earlier this is all making a lot more sense now.

>> anything or missing any nuances?  Would this code scale upward as I
>> would hope?
>
> It would be a bit messy but could be adapted quite easily.
> For example instead of the if/elif chain use a dictionary
> for event dispatch.

What would be the "messy" issues?  I suspect these are the things that
I am not intuitively seeing and only realize retrospectively after I
get deep into coding.

Thanks!

boB

From robertvstepp at gmail.com  Mon May 30 21:16:18 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 30 May 2016 20:16:18 -0500
Subject: [Tutor] Correct use of model-view-controller design pattern
In-Reply-To: <nihpqf$svc$1@ger.gmane.org>
References: <CANDiX9JqTD+Pwhd2n0ivGF=HNAf4vy1M6Y60dN97PAFrV9nQjA@mail.gmail.com>
 <nihpqf$svc$1@ger.gmane.org>
Message-ID: <CANDiX9+SuFhFoKaDSoPqxVgjQ0h8=SQvb8AjkK6dZ5xJPp0PFw@mail.gmail.com>

On Mon, May 30, 2016 at 11:30 AM, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 29/05/16 05:33, boB Stepp wrote:

>> 1)  If I were to add code to filter user inputs, which file is the
>> logical place to place such code?  My current impression is that it
>> should go in the controller, but I could see it being in the view.
>> However, if I were to write a Validation class, I could see that as
>> having uses beyond checking just user input.
>
> Filtering user input is one type of validation (others include
> type and value checking) Usually the view (especially in a GUI)
> will control the type checking and in  some cases the value
> checking too (think calendar pickers). But the controller may
> also do some data adjustment (such as reformatting a date
> to suit a particular model). But mostly I expect the view
> to collect the correct data in terms of primitive type/value.

I perhaps see a general principle developing here:  Before passing
data elsewhere, the data should be validated and in a form suitable
for where it is being sent.  In my simple code example, I was trying
to do this:  Change the diameter, which was currently in a string
format, to float prior to sending it to the model.  And likewise,
changing diameter and circumference back to strings prior to being
sent to the view.

> An example where more complex validation might be required is
> where you want to validate a credit card or an account number.
> In that case the controller may call a business service before
> passing the validated details onto the appropriate model(s)
> to process.

By "business service" are you intending this to mean a totally
different application, or just a different model within the same
overall program?

> Models should usually expect to be given good data. In some
> cases you might want to do a belt n' braces data check in
> the model too, but mostly you assume your front end is
> catching the bad stuff (see file processing below).

I take it "braces" are what we call "suspenders" in the US?  So what
you are talking about is redundant validation?  When would this be
actually called for as it seems to contradict DRY principles?  The
only thing that is coming to my mind now is code for something where
failure is not an option and the source of the incoming data (Which
should be doing proper validation.) was coded by someone else.  If I
were coding both myself, then I would think that I should be able to
trust that I did the job correctly the first time!


>> 3)  If I were to add data files in place of (or in addition to) user
>> input, in which aspect of MVC would file I/O be handled?
>
> This is where things get interesting. When processing files the
> view/controller are only likely to be validating the filename and
> initiating the process. This means that there needs to be a model object
> somewhere that processes the file. But the content of the
> file is unsafe  so that model needs to do all the data
> validation that would normally be done in the view/controller.
>
> Its not unusual to have a dedicated model for such batch processing
> and it will then call the other model methods for each record processed,
> effectively becoming a controller of sorts. There may
> be opportunities for code reuse between the UI controller and
> the batch controller.

I guess what I am getting out of this discussion of MVC, is to not be
too rigid in my thinking, but try to decouple these three broad areas
of responsibility as much as is practical, so as to make the resulting
code more maintainable and scalable.  Is this the correct big picture
idea?

Thanks!

boB

From robertvstepp at gmail.com  Mon May 30 21:25:04 2016
From: robertvstepp at gmail.com (boB Stepp)
Date: Mon, 30 May 2016 20:25:04 -0500
Subject: [Tutor] Correct use of model-view-controller design pattern
In-Reply-To: <niet9i$eqp$1@ger.gmane.org>
References: <CANDiX9JqTD+Pwhd2n0ivGF=HNAf4vy1M6Y60dN97PAFrV9nQjA@mail.gmail.com>
 <niet9i$eqp$1@ger.gmane.org>
Message-ID: <CANDiX9+S3We4uktr-m5FqG5x+LFgn=eSaFaHvqMfeq8L8XfYkw@mail.gmail.com>

One other thing I meant to ask about:

On Sun, May 29, 2016 at 9:10 AM, Alan Gauld via Tutor <tutor at python.org> wrote:

> The model responds, but how the view is notified varies. In some cases
> the views register with models and the model automatically sends
> notification messages to all registered views (by-passing the
> controller). In other cases the model si8mply sends a reply to the
> controller that invoked it and the controller decides which views should
> be updated.

This "views register with models" and "registered views" terminology
is unfamiliar to me.  Googling suggests registered views is referring
to a dynamically generated presentation, perhaps in the sense of a db
view.  I suspect I have an idea of what is being meant here, but
instead of potentially guessing, would you care to elaborate?

Thanks!

boB

From alan.gauld at yahoo.co.uk  Tue May 31 04:35:54 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 31 May 2016 09:35:54 +0100
Subject: [Tutor] Correct use of model-view-controller design pattern
In-Reply-To: <CANDiX9+S3We4uktr-m5FqG5x+LFgn=eSaFaHvqMfeq8L8XfYkw@mail.gmail.com>
References: <CANDiX9JqTD+Pwhd2n0ivGF=HNAf4vy1M6Y60dN97PAFrV9nQjA@mail.gmail.com>
 <niet9i$eqp$1@ger.gmane.org>
 <CANDiX9+S3We4uktr-m5FqG5x+LFgn=eSaFaHvqMfeq8L8XfYkw@mail.gmail.com>
Message-ID: <nijida$cg9$1@ger.gmane.org>

On 31/05/16 02:25, boB Stepp wrote:

> This "views register with models" and "registered views" terminology
> is unfamiliar to me.  Googling suggests registered views is referring
> to a dynamically generated presentation, perhaps in the sense of a db

No, this is different.
Try googling publish-subscribe instead.

The pattern is that something has data to publish (the model)
and other things want to know about when the data changes
(the associated view(s)). So when a view is created it knows which
model(s) it wants updates from and registers with them. (The model
has a register() method that adds the new view to a list of subscribers.)

When something changes on the model it calls its publish() method
which simply traverses the subscriber list and sends an update() message
to each (usually with itself as the argument).

The view can then interrogate the model to see if any of the
data changes affect its display and, if so, make the
corresponding updates on the UI.

When a view is deleted it unregisters from the model.

In summary:

- A view constructor must have a model parameter
  and register with the model.
- A view must implement an update() method
- A view destructor must unregister itself from the model

- A Model must have a register() method
- A Model must have an unregister() method
- A model must have a publish() method

This mechanism is most commonly used where the view/controller
are combined into a single implementation entity.

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



From alan.gauld at yahoo.co.uk  Tue May 31 04:49:36 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 31 May 2016 09:49:36 +0100
Subject: [Tutor] Correct use of model-view-controller design pattern
In-Reply-To: <CANDiX9+SuFhFoKaDSoPqxVgjQ0h8=SQvb8AjkK6dZ5xJPp0PFw@mail.gmail.com>
References: <CANDiX9JqTD+Pwhd2n0ivGF=HNAf4vy1M6Y60dN97PAFrV9nQjA@mail.gmail.com>
 <nihpqf$svc$1@ger.gmane.org>
 <CANDiX9+SuFhFoKaDSoPqxVgjQ0h8=SQvb8AjkK6dZ5xJPp0PFw@mail.gmail.com>
Message-ID: <nijj70$p02$1@ger.gmane.org>

On 31/05/16 02:16, boB Stepp wrote:

> I perhaps see a general principle developing here:  Before passing
> data elsewhere, the data should be validated and in a form suitable
> for where it is being sent.  

Correct.

> By "business service" are you intending this to mean a totally
> different application, or just a different model within the same
> overall program?

Either. It could even be a web service provided by a different
organisation altogether. This is quite common for credit checks
and the like. (Although a credit check would almost certainly
be done by a model rather than a controller... That falls into
business logic territory not presentation.)

> I take it "braces" are what we call "suspenders" in the US?  

I believe so. Suspenders in the UK are used to hold up your socks :-)

> you are talking about is redundant validation?  When would this be
> actually called for as it seems to contradict DRY principles?  

Correct. The file handling example is a case where it might be valid
since the model may use the same method to process a line from a file as
a record from the UI. However some OOP practitioners like to build some
validation into models anyway because models are often reusable in non
UI context - eg batch processing jobs - where there is no front end
validation.

Another case is where an organisation publishes its model API behind a
web service. Can you trust your web clients to validate? Maybe not. So
you either validate in the web service code or in the model.

Yet another case is where you handle mission critical shared data. If
you are writing that data into a central database shared with multiple
applications you need to be sure you don't corrupt it so you may add
some validation, just in case...

> only thing that is coming to my mind now is code for something where
> failure is not an option and the source of the incoming data (Which
> should be doing proper validation.) was coded by someone else.  If I
> were coding both myself, then I would think that I should be able to
> trust that I did the job correctly the first time!

Absolutely right.

> I guess what I am getting out of this discussion of MVC, is to not be
> too rigid in my thinking, but try to decouple these three broad areas
> of responsibility as much as is practical, so as to make the resulting
> code more maintainable and scalable.  Is this the correct big picture
> idea?

Yes, although for any given implementation you should decide the
responsibilities and stick to them. I'm currently doing a lot of Java
coding and the Java Swing UI framework has a very specific and rigid
take on MVC and you have to use that definition of the UI simply won't
work! So the framework you choose will often determine how you use MVC.
But in the bigger picture it is a set of principles.

MVC is one specific version of the more general programming rule to
separate presentation from business logic.

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



From min786a at googlemail.com  Tue May 31 11:16:21 2016
From: min786a at googlemail.com (marat murad)
Date: Tue, 31 May 2016 16:16:21 +0100
Subject: [Tutor] Help with 'if' statement and the concept of None
Message-ID: <CANeHpPL-6LhjEXVgmjfEnDUvezwyrNC=aUUOsqZ0cTSDyvpNcA@mail.gmail.com>

Hi
I'm learning how to code with python an I have purchased the book 'Python
Programming for the absolute beginner,third edition' by Michael Dawson.
There is one concept that is confusing me in chapter 3 page 71 there is a
program  whose code I have pasted below. The author introduced a new way of
coding the Boolean NOT operator with the 'if' statement I have highlighted
the relevant area,apparently this if statement actually means if money !=
0,which I understood,but the program below this one which introduces the
idea of slicing also has a if statement similar to the first one,except the
second one accepts  0 value but the first one doesn't.

print("Welcome to the Chateau D'food")
print("It seems we are quit full today.\n")

money = int(input("How many dollars do you slip the Maitr D'? "))

*if money:*
    print("Ah I think I can make something work")
else:
    print("Please sit ,it may be a while")


input("\nPress enter to exit")


The slicing program

word = "existential"

print("Enter the beginning and ending index for the word existential")
print("press he enter key at 'Start' to exit")

start= None
while start != "":
    start=input("\nStart: ")

   * if start:*
        start=int(start)

        finish=int(input("Finish: "))

        print ("word[",start, ":",finish, "]is " , end="")
        print(word[start:finish])

input("\nPress enter to exit")

I hope i made sense.

Thankyou

From vkatz722 at gmail.com  Tue May 31 11:30:29 2016
From: vkatz722 at gmail.com (Vadim Katsemba)
Date: Tue, 31 May 2016 11:30:29 -0400
Subject: [Tutor] Python OLS help
Message-ID: <CA+5SJ0eVbVe7CGeD=wwtQ3-NP_cF6odengKhDhxK+H4ObGoM+Q@mail.gmail.com>

Hello there, I am having trouble running the Ordinary Least Squares (OLS)
regression on Spyder. I typed in lm =
smf.ols(formula='LATITUDE~DIAMETER',data=dataf).fit(), and I ended up
getting this error: ValueError: For numerical factors, num_columns must be
an int. How am I supposed to run the OLS, is there another module I need to
use? Any help would be appreciated.

From alan.gauld at yahoo.co.uk  Tue May 31 18:06:47 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 31 May 2016 23:06:47 +0100
Subject: [Tutor] Help with 'if' statement and the concept of None
In-Reply-To: <CANeHpPL-6LhjEXVgmjfEnDUvezwyrNC=aUUOsqZ0cTSDyvpNcA@mail.gmail.com>
References: <CANeHpPL-6LhjEXVgmjfEnDUvezwyrNC=aUUOsqZ0cTSDyvpNcA@mail.gmail.com>
Message-ID: <nil1tn$9b8$1@ger.gmane.org>

On 31/05/16 16:16, marat murad via Tutor wrote:

> program  whose code I have pasted below. The author introduced a new way of
> coding the Boolean NOT operator with the 'if' statement I have highlighted
> the relevant area,apparently this if statement actually means if money !=
> 0,which I understood,

Boolean values are either true or false.
Other values are given boolean equivalent values by Python.
eg. For strings an empty string is False, anything else is True.
For numbers 0 is False anything else is True.

So in your example:

> *if money:*
>     print("Ah I think I can make something work")
> else:
>     print("Please sit ,it may be a while")
>

The first 'if' test is saying

'if money is equivalent to True' (anything other than zero)

In effect that's the same as you said (it's like testing for != 0)
but the important difference is that it is relying
on the boolean *equivalence* of an integer value.
The same is true in your second example:

> idea of slicing also has a if statement similar to the first one,except the
> second one accepts  0 value but the first one doesn't.
> 

>     start=input("\nStart: ")
> 
>    * if start:*
>         start=int(start)

Again this is really saying if start is True and for a string
(which is what input() returns), as I said above, True means
not empty. So the string '0' is not empty and therefore True.
It's not the value of the character that matters it's the fact
that there is a character there at all.

All objects in Python have these boolean equivalent values,
for example an empty list, tuple,set or dictionary is also
considered False. As is the special value None.

> I hope i made sense.

Yes, although your subject also mentions the concept of None?
Did you have another question about that?

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



From alan.gauld at yahoo.co.uk  Tue May 31 18:10:49 2016
From: alan.gauld at yahoo.co.uk (Alan Gauld)
Date: Tue, 31 May 2016 23:10:49 +0100
Subject: [Tutor] Python OLS help
In-Reply-To: <CA+5SJ0eVbVe7CGeD=wwtQ3-NP_cF6odengKhDhxK+H4ObGoM+Q@mail.gmail.com>
References: <CA+5SJ0eVbVe7CGeD=wwtQ3-NP_cF6odengKhDhxK+H4ObGoM+Q@mail.gmail.com>
Message-ID: <nil259$cpn$1@ger.gmane.org>

On 31/05/16 16:30, Vadim Katsemba wrote:
> Hello there, I am having trouble running the Ordinary Least Squares (OLS)
> regression on Spyder. 

I had no idea what Spyder was but a Google search says its an IDE
somewhat akin to matlab or IPython... It also has a discussion group:

http://groups.google.com/group/spyderlib

You may find someone on this list who knows it but you will likely
get a better response on the spyder forum. This list is really
for core python language questions and although we try to be
helpful on other matters a dedicated forum is usually better.


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



From steve at pearwood.info  Tue May 31 20:12:08 2016
From: steve at pearwood.info (Steven D'Aprano)
Date: Wed, 1 Jun 2016 10:12:08 +1000
Subject: [Tutor] Help with 'if' statement and the concept of None
In-Reply-To: <CANeHpPL-6LhjEXVgmjfEnDUvezwyrNC=aUUOsqZ0cTSDyvpNcA@mail.gmail.com>
References: <CANeHpPL-6LhjEXVgmjfEnDUvezwyrNC=aUUOsqZ0cTSDyvpNcA@mail.gmail.com>
Message-ID: <20160601001208.GA12028@ando.pearwood.info>

On Tue, May 31, 2016 at 04:16:21PM +0100, marat murad via Tutor wrote:

> money = int(input("How many dollars do you slip the Maitr D'? "))
> *if money:*
>     print("Ah I think I can make something work")
> else:
>     print("Please sit ,it may be a while")

All values in Python can be used where a true or false boolean value is 
expected, such as in an "if" or a "while" statement. We call this a 
"boolean context", meaning something which expects a true or false flag.

So we have True and False (with the initial capital letter) as special 
constants, but we also can treat every other value as if they were true 
or false (without the initial capital). Sometimes we call them "truthy" 
and "falsey", or "true-like" and "false-like" values.

For Python built-ins, we have:

Falsey (false-like) values:

- zero: 0, 0.0, 0j, Fraction(0), etc.
- empty strings: "", b""
- empty containers: [], (), {}, set() etc.
  (empty list, empty tuple, empty dict, empty set)
- sequences with len() == 0
- None
- False

Truthy (true-like) values:

- non-zero numbers: 1, 2.0, 3j, Fraction(4, 5), etc.
- non-empty strings: "Hello world!", b"\x0"
  (yes, even the null-byte is non-empty, since it has length 1)
- non-empty containers
- sequences with len() != 0
- classes, object()
- True

We say that "false values represent nothing", like zero, empty strings, 
None, and empty containers; while "true values represent something", 
that is, anything which is not nothing.


So any time you have a value, say, x, we can test to see if x is a 
truthy or falsey value:


values = [1, 5, 0, -2.0, 3.7, None, object(), (1, 2), [], True]
for x in values:
    if x:
        print(x, "is a truthy value")
    else:
        print(x, "is a falsey value")




-- 
Steve

From ben+python at benfinney.id.au  Tue May 31 20:58:58 2016
From: ben+python at benfinney.id.au (Ben Finney)
Date: Wed, 01 Jun 2016 10:58:58 +1000
Subject: [Tutor] Help with 'if' statement and the concept of None
References: <CANeHpPL-6LhjEXVgmjfEnDUvezwyrNC=aUUOsqZ0cTSDyvpNcA@mail.gmail.com>
Message-ID: <858typ7mi5.fsf@benfinney.id.au>

marat murad via Tutor <tutor at python.org> writes:

> The author introduced a new way of coding the Boolean NOT operator
> with the 'if' statement I have highlighted the relevant
> area,apparently this if statement actually means if money != 0,which I
> understood

Not quite. The statement actually means ?if ?money? evaluates as true?.

Any Python value can be interrogated with the question ?Are you true or
false??, and that is what the ?if? statement does.

This is different from asking ?Is this the True constant or the False
constant?? because for most values the answer is ?Neither?.

In Python the question ?Is this value true, or false?? is usually
implemented as ?Is this value something, or nothing??. If the value is
conceptually nothing, it evaluates as false when interrogated in a
boolean context.

See the Python documentation for a comprehensive list of false values
<URL:https://docs.python.org/3/library/stdtypes.html#truth-value-testing>;
any not-false value is true by default.

If you learn the conceptual ?if it's not something, it's false?, then
you will have a fairly good intuition for how ?if somevalue? works.

-- 
 \        ?None can love freedom heartily, but good men; the rest love |
  `\                           not freedom, but license.? ?John Milton |
_o__)                                                                  |
Ben Finney


From michael.selik at gmail.com  Tue May 31 20:03:18 2016
From: michael.selik at gmail.com (Michael Selik)
Date: Wed, 01 Jun 2016 00:03:18 +0000
Subject: [Tutor] Python OLS help
In-Reply-To: <CA+5SJ0eVbVe7CGeD=wwtQ3-NP_cF6odengKhDhxK+H4ObGoM+Q@mail.gmail.com>
References: <CA+5SJ0eVbVe7CGeD=wwtQ3-NP_cF6odengKhDhxK+H4ObGoM+Q@mail.gmail.com>
Message-ID: <CAGgTfkOgy89Xw1V1A2_ai3-=wWynDx8sDGnrD+e5s0nUzQAmEg@mail.gmail.com>

On Tue, May 31, 2016 at 5:45 PM Vadim Katsemba <vkatz722 at gmail.com> wrote:

> I typed in lm = smf.ols(formula='LATITUDE~DIAMETER',data=dataf).fit(), and
> I ended up getting this error: ValueError: For numerical factors,
> num_columns must be an int.
>

You may be using an old version of Patsy, the module that allows you to
specify your OLS formula like R-lang does. What version of patsy are you
using? This seems to have been a problem with Patsy v0.4.0 and was fixed in
v0.4.1 (as per an email thread I read [0])

[0] https://groups.google.com/forum/#!topic/pystatsmodels/KcSzNqDxv-Q