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: 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 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: 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 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 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: On Sun, May 1, 2016 at 12:35 AM, wrote: > On 01May2016 14:18, Steven D'Aprano 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: References: Message-ID: On Sun, May 1, 2016 at 1:02 AM, boB Stepp 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: References: Message-ID: 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: Message-ID: <85zisago5u.fsf@benfinney.id.au> Katie Tuite 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: 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: 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: References: <20160501041826.GB13497@ando.pearwood.info> Message-ID: 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: References: <20160501041826.GB13497@ando.pearwood.info> <20160501053546.GA3946@cskk.homeip.net> Message-ID: 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: References: 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: 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: References: Message-ID: On May 1, 2016 8:04 AM, "Olaoluwa Thomas" 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: References: Message-ID: On May 1, 2016 4:33 AM, "Katie Tuite" 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: 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 wrote: > On Sun, May 01, 2016 at 5:34 PM, Olaoluwa Thomas > 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 wrote: > > On May 1, 2016 8:04 AM, "Olaoluwa Thomas" > 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: 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=''' ACCT2081''' 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: Message-ID: 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=''' > 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''' > > > 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: References: Message-ID: 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 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 > wrote: > >> On Sun, May 01, 2016 at 5:34 PM, Olaoluwa Thomas >> 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 wrote: >> >> >> On May 1, 2016 8:04 AM, "Olaoluwa Thomas" >> 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: References: 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: References: Message-ID: 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 "", line 1, in 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: References: Message-ID: 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: References: Message-ID: On 01/05/16 17:49, bruce wrote: > Hi. I have a chunk of text code, which has multiple lines. > s=''' > 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''' 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: References: Message-ID: Gotcha. *Warm regards,* *Olaoluwa O. Thomas,* *+2347068392705* On Sun, May 1, 2016 at 7:14 PM, Alan Gauld via Tutor 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 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: <20160501104338.GC13497@ando.pearwood.info> Message-ID: On Sun, May 1, 2016 at 5:43 AM, Steven D'Aprano 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: References: 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 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 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: 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 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: References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com> <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com> Message-ID: 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 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 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: References: <6553cfb329696cf0af811372403c575a@sonic.net> <20160428101156.GS13497@ando.pearwood.info> Message-ID: 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 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: References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com> <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com> Message-ID: 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: References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com> <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.com> Message-ID: On May 2, 2016 5:27 PM, "Jason N. via Tutor" 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: References: <2071115180.5209339.1462224414847.JavaMail.yahoo.ref@mail.yahoo.com> <2071115180.5209339.1462224414847.JavaMail.yahoo@mail.yahoo.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 wrote: On May 2, 2016 5:27 PM, "Jason N. via Tutor" 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> <488374863.5194217.1462237016676.JavaMail.yahoo@mail.yahoo.com> Message-ID: 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 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 wrote: > > > > >> On May 2, 2016 5:27 PM, "Jason N. via Tutor" 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. 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 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: References: Message-ID: On Sun, May 1, 2016 at 9:49 AM, bruce 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: <85zisago5u.fsf@benfinney.id.au> Message-ID: On Sun, May 1, 2016 at 1:47 AM, Ben Finney wrote: > Katie Tuite 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: 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 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 wrote: On May 2, 2016 5:27 PM, "Jason N. via Tutor" 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: References: Message-ID: 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: References: Message-ID: <5728E776.2020601@gmail.com> On May 3, 2016 3:04 AM, "Katie Tuite" > 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> <488374863.5194217.1462237016676.JavaMail.yahoo@mail.yahoo.com> Message-ID: On Mon, May 2, 2016 at 8:58 PM Jason N. via Tutor 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: On Mon, May 2, 2016 at 5:28 PM Jason N. via Tutor 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: References: Message-ID: Thanks, Alan. Have a great day. Henry On Wed, May 4, 2016 at 12:00 AM, 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 > To: tutor at python.org > Subject: Re: [Tutor] sqlite > Message-ID: > 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: References: <5728E776.2020601@gmail.com> Message-ID: On May 3, 2016 2:38 PM, "Katie Tuite" 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: 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: 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: References: 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: 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: References: <20160501041826.GB13497@ando.pearwood.info> 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: References: <20160501041826.GB13497@ando.pearwood.info> Message-ID: 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: On Sun, May 8, 2016 at 6:07 AM, Hunter Jozwiak 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: On Sun, May 8, 2016, 12:34 PM Hunter Jozwiak 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: 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: 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: References: <20160508.101444.16108.0@webmail13.dca.untd.com> Message-ID: I like the euler project On Sun, May 8, 2016 at 8:00 PM, Alan Gauld via Tutor 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: On Sun, May 8, 2016 at 12:14 PM, 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: 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('', mt) canvas.bind_all('', mt) canvas.bind_all('', mt) canvas.bind_all('', 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('', mt) '4300440008mt' >>> canvas.bind_all('', mt) '4329736584mt' >>> canvas.bind_all('', mt) '4380738824mt' >>> canvas.bind_all('', 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: References: Message-ID: On May 9, 2016 8:01 AM, "Lisa Hasler Waters" 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('', mt) > canvas.bind_all('', mt) > canvas.bind_all('', mt) > canvas.bind_all('', 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('', mt) > '4300440008mt' > >>> canvas.bind_all('', mt) > '4329736584mt' > >>> canvas.bind_all('', mt) > '4380738824mt' > >>> canvas.bind_all('', 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: References: Message-ID: 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 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('', mt) > canvas.bind_all('', mt) > canvas.bind_all('', mt) > canvas.bind_all('', 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: Message-ID: 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('', mt) canvas.bind_all('', mt) canvas.bind_all('', mt) canvas.bind_all('', 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: References: Message-ID: 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: On Mon, May 9, 2016 at 4:13 AM, Chris Roy-Smith 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: 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: References: Message-ID: On Mon, May 9, 2016 at 11:34 AM, Alan Gauld via Tutor 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: References: Message-ID: 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 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: 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 """""" for row in line1: print """"""+str(row)+"""""" print """""" 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: Message-ID: 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 """""" > for row in line1: > print """"""+str(row)+"""""" > print """""" > > 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: 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: References: <573046AC.2000401@internode.on.net> <5730FB24.9020801@gybon.cz> Message-ID: On Mon, May 9, 2016 at 6:49 PM, Alan Gauld via Tutor 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: References: Message-ID: 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 """""" > for row in line1: > print """"""+str(row)+"""""" > print """""" > > 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: References: Message-ID: 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 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 """""" >> for row in line1: >> print """"""+str(row)+"""""" >> print """""" >> >> 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: Message-ID: 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: References: Message-ID: IT WORKED !!!! THANK YOU SSSOOOO MUCH ...phew .. Thank you here is the result. 1 ('Supervisor',) 1 Vinayak Salunke 1 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: 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: References: Message-ID: 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: References: 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: References: Message-ID: On 10 May 2016 at 04:08, 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? > > 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: References: Message-ID: > here is the result. > > 1 > ('Supervisor',) > > 1 > Vinayak > Salunke > 1 > > 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 """"""+str(row)+"""""" 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: References: Message-ID: On 10/05/16 08:33, nitin chandra wrote: > here is the result. > > 1 > ('Supervisor',) > > 1 > Vinayak > Salunke > 1 > > 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: References: Message-ID: 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 wrote: > On 10/05/16 08:33, nitin chandra wrote: > >> here is the result. >> >> 1 >> ('Supervisor',) >> >> 1 >> Vinayak >> Salunke >> 1 >> >> 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: References: Message-ID: On Tue, May 10, 2016 at 10:37 PM, nitin chandra 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: 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: References: Message-ID: <20160511224245.GA22481@cskk.homeip.net> On 11May2016 14:00, khalil zakaria Zemmoura 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 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: References: 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: <20160512011921.GE12028@ando.pearwood.info> Message-ID: 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 "" ... >>> int(Key()) Traceback (most recent call last): File "", line 1, in 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 {: '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: References: <20160512011921.GE12028@ando.pearwood.info> Message-ID: 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 "" ... >>> int(Key()) Traceback (most recent call last): File "", line 1, in 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 {: '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: References: Message-ID: 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: References: Message-ID: 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: Message-ID: 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: 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: References: Message-ID: On Sun, May 15, 2016 at 5:45 PM, 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'. > > > 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: References: 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: References: Message-ID: 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: 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: References: 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: References: Message-ID: 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: References: 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: References: Message-ID: <20160517090148.GA41951@cskk.homeip.net> On 17May2016 04:28, Chris Kavanagh 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 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: <20160517090148.GA41951@cskk.homeip.net> Message-ID: 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, wrote: > On 17May2016 04:28, Chris Kavanagh 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 > 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: References: <20160517090148.GA41951@cskk.homeip.net> Message-ID: 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: References: <20160517090148.GA41951@cskk.homeip.net> 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: References: Message-ID: 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: 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: References: Message-ID: 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: 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: References: 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: 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: References: Message-ID: 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: 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: References: Message-ID: 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: 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: Message-ID: 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: 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: 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('Peckerwood Garden Docent Notes\n') htmlpage.write('') htmlpage.write('') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\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('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('\n') htmlpage.write('') htmlpage.write('\n') htmlpage.write('
Unique IDLocationNameFamilyCommon NameNativityPhotographsDescription
' + uniqueid + '' + location + '' + name + '' + family + '' + commonname + '' + nativity + '') for x in glob.glob(imagesdirectory + uniqueid + '*'): htmlpage.write ('Photo\n') htmlpage.write('' + description +'
') 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: Photo Photo 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: Photo Photo Peckerwood Garden Docent Notes\n') > htmlpage.write('') > htmlpage.write('') > htmlpage.write('\n') > htmlpage.write('\n') > htmlpage.write('\n') > htmlpage.write('\n') > htmlpage.write('\n') > htmlpage.write('\n') > htmlpage.write('\n') > htmlpage.write('\n') > htmlpage.write('\n') > htmlpage.write('\n') > htmlpage.write('\n') > htmlpage.write('\n') > htmlpage.write('\n') Consider using triple quoted strings to save yourself a lot of typing and to make the html easier to read. > ... > htmlpage.write('') > htmlpage.write('\n') > htmlpage.write('
Unique IDLocationNameFamilyCommon NameNativityPhotographsDescription
' + description +'
') > 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: 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: References: Message-ID: 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 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('> charset="UTF-8">Peckerwood Garden Docent Notes\n') >> htmlpage.write('') >> htmlpage.write('') >> htmlpage.write('\n') >> htmlpage.write('\n') >> htmlpage.write('\n') >> htmlpage.write('\n') >> htmlpage.write('\n') >> htmlpage.write('\n') >> htmlpage.write('\n') >> htmlpage.write('\n') >> htmlpage.write('\n') >> htmlpage.write('\n') >> htmlpage.write('\n') >> htmlpage.write('\n') >> htmlpage.write('\n') > > Consider using triple quoted strings to save yourself a lot of typing > and to make the html easier to read. > >> ... >> htmlpage.write('') >> htmlpage.write('\n') >> htmlpage.write('
Unique IDLocationNameFamilyCommon NameNativityPhotographsDescription
' + description +'
') >> 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: 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: References: Message-ID: 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: References: Message-ID: 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: References: Message-ID: Dear Peter & Alan, Thanks alot. Have a great day Cheers, Hank On Fri, May 20, 2016 at 12:00 AM, 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: > 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: References: Message-ID: On Thu, May 19, 2016 at 12:34 PM, Terry Carroll 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: 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: 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: References: <1149552750.559391463742798753.JavaMail.httpd@webmail-60.iol.local> Message-ID: 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: On Fri, May 20, 2016 at 7:16 AM jarod_v6--- via Tutor 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: 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: References: Message-ID: 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: References: Message-ID: (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: 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: []" *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: Message-ID: <854m9qc2yb.fsf_-_@benfinney.id.au> Albert-Jan Roskam 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: Message-ID: <85ziriao4f.fsf@benfinney.id.au> Terry Carroll 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) 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 . Test behaviour of the whole program, too, with behavioural tests . 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: Message-ID: <85vb26anz1.fsf@benfinney.id.au> Saidov 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: []" 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: References: 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 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: []" 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 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: References: 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: []" > > *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 "", line 1, in decimal.InvalidOperation: [] 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: <20160522033139.GA53172@cskk.homeip.net> Message-ID: 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 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 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: []" 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 + 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 ipython traceback: row[4]= ' "" ' Traceback (most recent call last): File "C:\mypath\visual studio 2015\Projects\Budget\Budget\Budget.py", line 28, in expenses[ts.Date(row[0]).month] += decimal.Decimal(row[4]) decimal.InvalidOperation: [] 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 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: References: <20160522033139.GA53172@cskk.homeip.net> Message-ID: 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: References: Message-ID: <20160522223629.GA12844@cskk.homeip.net> On 22May2016 08:19, Saidov 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 >+ 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 '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 > expenses[ts.Date(row[0]).month] += decimal.Decimal(row[4]) >decimal.InvalidOperation: [] > >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 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: 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: <20160522223629.GA12844@cskk.homeip.net> Message-ID: On Sun, May 22, 2016 at 5:36 PM, wrote: > On 22May2016 08:19, Saidov 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 >> + 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 > '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 >> expenses[ts.Date(row[0]).month] += decimal.Decimal(row[4]) >> decimal.InvalidOperation: [] >> >> 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 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 = unexpected expenses value: '($10.00)' row[4] = '($287.42)' value type = 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: References: <20160522223629.GA12844@cskk.homeip.net> Message-ID: 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: References: Message-ID: 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: <20160522223629.GA12844@cskk.homeip.net> Message-ID: 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 = > unexpected expenses value: '($10.00)' > row[4] = '($287.42)' value type = > 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: References: 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: References: <20160522223629.GA12844@cskk.homeip.net> Message-ID: 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 = >> unexpected expenses value: '($10.00)' >> row[4] = '($287.42)' value type = >> 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: References: Message-ID: <20160524015003.GA44454@cskk.homeip.net> On 23May2016 12:18, Saidov 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 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: 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: <20160524015003.GA44454@cskk.homeip.net> Message-ID: cs at zip.com.au wrote: > On 23May2016 12:18, Saidov 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: References: Message-ID: 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: References: Message-ID: Hi, On 24 May 2016 at 04:17, Crusier 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 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 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 " 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: References: Message-ID: On 24 May 2016 at 15:37, Walter Prins 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: On Mon, May 23, 2016 at 5:08 PM, Terry--gmail 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: 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: 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 *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 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: Message-ID: <85mvnf9c7p.fsf@benfinney.id.au> Terry Carroll 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: References: Message-ID: 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 wrote: > On 24 May 2016 at 15:37, Walter Prins 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: > 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: 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 "", line 1, in > 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: Message-ID: 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: References: Message-ID: 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: 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: 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: References: Message-ID: 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: Message-ID: 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: References: Message-ID: 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 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: References: Message-ID: 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 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: References: Message-ID: 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 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: References: Message-ID: > 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: 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: Message-ID: <858tyw9xbu.fsf@benfinney.id.au> Max Jegers 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 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: References: Message-ID: 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: 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 .') 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: References: Message-ID: 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 .') > 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: Message-ID: 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 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("", 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: References: 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: References: 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: 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: 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: References: Message-ID: 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: References: <57437F6D.9010808@gmail.com> 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: References: Message-ID: 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 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> <574C74A8.1040700@gmail.com> Message-ID: On Mon, May 30, 2016 at 12:13 PM, 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 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> <574C76AD.6020209@gmail.com> Message-ID: 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: References: <57437F6D.9010808@gmail.com> 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: References: Message-ID: 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: References: Message-ID: <20160530230757.GF22214@raspberrypi> * 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 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: References: Message-ID: 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: , , <20160530230757.GF22214@raspberrypi> Message-ID: 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: References: Message-ID: Thank you for the reply. On 30/05/2016 3:45 PM, "Steve Lett" 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: References: <57437F6D.9010808@gmail.com> <574C76AD.6020209@gmail.com> 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: References: Message-ID: On Sun, May 29, 2016 at 9:10 AM, Alan Gauld via Tutor 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: References: Message-ID: On Mon, May 30, 2016 at 11:30 AM, Alan Gauld via Tutor 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: References: Message-ID: One other thing I meant to ask about: On Sun, May 29, 2016 at 9:10 AM, Alan Gauld via Tutor 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: References: Message-ID: 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: References: Message-ID: 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: 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: 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: References: Message-ID: 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: References: Message-ID: 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: References: 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: Message-ID: <858typ7mi5.fsf@benfinney.id.au> marat murad via Tutor 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 ; 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: References: Message-ID: On Tue, May 31, 2016 at 5:45 PM Vadim Katsemba 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