From guirguismichel at yahoo.co.uk Thu Oct 1 09:48:57 2015 From: guirguismichel at yahoo.co.uk (Michel Guirguis) Date: Thu, 1 Oct 2015 10:48:57 +0300 Subject: [Tutor] Cumulative distribution function Message-ID: Good morning, I have a problem with the cumulative distribution function in calculating derivatives. I am getting a call option figure of 2.5961 while it should be 2.9081. Could you please help. >>>S=50 >>> K=50 >>> r=0.03 >>> q=0.02 >>> sig=0.20 >>> T=0.5 >>> from math import* >>> d1=(log(S/K)+(r-q+(sig*sig)*0.5)*T)/(sig*sqrt(T)) >>> d1 0.10606601717798211 >>> d2 =d1-sig*sqrt(T) >>> d2 -0.03535533905932742 >>> def cumdist(): call = 50*exp(-0.02*0.5)*cumdist*(d1)-50*exp(-0.03*0.5)*cumdist*(d2) >>> call 2.596102990952506 Thanks, Michel From lac at openend.se Thu Oct 1 10:36:17 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 01 Oct 2015 10:36:17 +0200 Subject: [Tutor] Cumulative distribution function In-Reply-To: References: Message-ID: <201510010836.t918aHXQ015831@fido.openend.se> In a message of Thu, 01 Oct 2015 10:48:57 +0300, Michel Guirguis writes: >Good morning, > >I have a problem with the cumulative distribution function in calculating derivatives. I am getting a call option figure of 2.5961 while it should be 2.9081. Could you please help. > > >>>S=50 >>>> K=50 >>>> r=0.03 >>>> q=0.02 >>>> sig=0.20 >>>> T=0.5 > >>>> from math import* >>>> d1=(log(S/K)+(r-q+(sig*sig)*0.5)*T)/(sig*sqrt(T)) >>>> d1 >0.10606601717798211 >>>> d2 =d1-sig*sqrt(T) >>>> d2 >-0.03535533905932742 >>>> def cumdist(): >call = 50*exp(-0.02*0.5)*cumdist*(d1)-50*exp(-0.03*0.5)*cumdist*(d2) > > >>>> call >2.596102990952506 > >Thanks, > >Michel I do not know if this is your problem, but you can get significant errors if you try to use binary floating point to represent money. You should use decimal floating point instead. see: https://docs.python.org/3.4/library/decimal.html Laura From __peter__ at web.de Thu Oct 1 10:57:18 2015 From: __peter__ at web.de (Peter Otten) Date: Thu, 01 Oct 2015 10:57:18 +0200 Subject: [Tutor] Cumulative distribution function References: Message-ID: Michel Guirguis wrote: [Please don't start a new thread for an old problem] > I have a problem with the cumulative distribution function in calculating > derivatives. I am getting a call option figure of 2.5961 while it should > be 2.9081. Could you please help. > >>> S=50 > >>> K=50 > >>> r=0.03 > >>> q=0.02 > >>> sig=0.20 > >>> T=0.5 > >>> from math import* > >>> d1=(log(S/K)+(r-q+(sig*sig)*0.5)*T)/(sig*sqrt(T)) > >>> d1 > 0.10606601717798211 > >>> d2 =d1-sig*sqrt(T) > >>> d2 > -0.03535533905932742 > >>> def cumdist(): Something is missing here... > call = 50*exp(-0.02*0.5)*cumdist*(d1)-50*exp(-0.03*0.5)*cumdist*(d2) ... and here seem to be erroneous * operators. > >>> call > 2.596102990952506 Did you see Laura's answer to your previous question? Using scipy.stats.norm.cdf and turning your interactive session into a little script I get $ cat cumulative.py import scipy.stats from math import log, exp, sqrt cumdist = scipy.stats.norm.cdf S = 50 K = 50 r = 0.03 q = 0.02 sig = 0.20 T = 0.5 d1 = (log(S/K)+(r-q+(sig*sig)*0.5)*T)/(sig*sqrt(T)) print("d1 = {}".format(d1)) d2 = d1-sig*sqrt(T) print("d2 = {}".format(d2)) call = 50*exp(-0.02*0.5)*cumdist(d1)-50*exp(-0.03*0.5)*cumdist(d2) print("call = {}".format(call)) $ python cumulative.py d1 = 0.106066017178 d2 = -0.0353553390593 call = 2.9087784079 Not exactly 2.9081, but closer :) Assuming 2.9088 is the correct value, but for some reason you cannot use scipy the problem is with your cumdist() function. You don't provide that function and you don't provide the source where you adapted it from. How do you expect us to help you fix code without spec -- and without seeing said code? From lac at openend.se Thu Oct 1 12:26:26 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 01 Oct 2015 12:26:26 +0200 Subject: [Tutor] Cumulative distribution function In-Reply-To: References: Message-ID: <201510011026.t91AQQSF024003@fido.openend.se> In a message of Thu, 01 Oct 2015 10:57:18 +0200, Peter Otten writes: >$ python cumulative.py >d1 = 0.106066017178 >d2 = -0.0353553390593 >call = 2.9087784079 > >Not exactly 2.9081, but closer :) And sort of in the 'this is a float not a decimal' range I consider usual for such errors, not the huge difference you reported. >Assuming 2.9088 is the correct value, but for some reason you cannot use >scipy the problem is with your cumdist() function. I think we should work on getting you scipy. I think you are going to need plenty of things from there ... Laura From guirguismichel at yahoo.co.uk Thu Oct 1 14:42:25 2015 From: guirguismichel at yahoo.co.uk (Michel Guirguis) Date: Thu, 1 Oct 2015 15:42:25 +0300 Subject: [Tutor] Which header to use in python Message-ID: <9D65F49B-9C3C-4D6F-BF12-4C90ACE82B84@yahoo.co.uk> Good afternoon, What is the name of the header that I can use in Python 3.4 to convert the cumulative distribution function number 0.10606601717798211 to 0.54223501331161406 from scipy.stats import norm norm.cdf(0.10606601717798211) 0.54223501331161406 Thanks, Michel From alan.gauld at btinternet.com Thu Oct 1 17:16:03 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 1 Oct 2015 16:16:03 +0100 Subject: [Tutor] Which header to use in python In-Reply-To: <9D65F49B-9C3C-4D6F-BF12-4C90ACE82B84@yahoo.co.uk> References: <9D65F49B-9C3C-4D6F-BF12-4C90ACE82B84@yahoo.co.uk> Message-ID: On 01/10/15 13:42, Michel Guirguis wrote: > What is the name of the header that I can use in Python 3.4 Can you explain what you mean by "header"? That's not a Python concept, Python doesn't have header files like C/C++ > to convert the cumulative distribution function number > 0.10606601717798211 to 0.54223501331161406 > > from scipy.stats import norm > > norm.cdf(0.10606601717798211) > 0.54223501331161406 I'm not sure what this shows? Is it a session from the interpreter? Or is it what you would like to happen? Can you clarify what it is you want to know? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From lac at openend.se Thu Oct 1 17:17:32 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 01 Oct 2015 17:17:32 +0200 Subject: [Tutor] Which header to use in python In-Reply-To: <9D65F49B-9C3C-4D6F-BF12-4C90ACE82B84@yahoo.co.uk> References: <9D65F49B-9C3C-4D6F-BF12-4C90ACE82B84@yahoo.co.uk> Message-ID: <201510011517.t91FHWwV012342@fido.openend.se> In a message of Thu, 01 Oct 2015 15:42:25 +0300, Michel Guirguis writes: >Good afternoon, > >What is the name of the header that I can use in Python 3.4 to convert the cumulative distribution function number 0.10606601717798211 to 0.54223501331161406 > >from scipy.stats import norm > >norm.cdf(0.10606601717798211) > 0.54223501331161406 > >Thanks, > >Michel You need scipy. It's called a package, not a header, by the way. scipy is the Scientific Python Package. It's not part of standard Python 3.4. The best way to get scypi is to go here: https://www.continuum.io/downloads and get Anaconda Python. Download the proper installer for whatever operating system you have. You are going to get yourself a whole new python 3.4 which will already have scipy, numpy and a ton of other scientific algorithms you will find useful. All your existing 3.4 programs will work perfectly well with it, so if you downloaded the 3.4 you are currently using yourself, you can go ahead and remove it and just use the one from Anaconda. What Operating system are you using, by the way? Laura From alan.gauld at btinternet.com Thu Oct 1 17:37:12 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 1 Oct 2015 16:37:12 +0100 Subject: [Tutor] Which header to use in python In-Reply-To: References: <9D65F49B-9C3C-4D6F-BF12-4C90ACE82B84@yahoo.co.uk> Message-ID: <560D5328.6090606@btinternet.com> On 01/10/15 16:23, Michel Guirguis wrote: > Good afternoon, > > Basically, I am trying to find a value of the cumulative distribution > in Python. > > Thanks for your help. I have managed to find the cumulative value in > scipy but not in the standard Python 3.4. I have solved my problem > with scipy but not with the standard Python 3.4. That's because Python does not have a rich set of statistical functions built in (it is a general purpose programming language) so you would need to create your own. That's why there are packages like scipy - to save you from writing your own. If you can provide the algorithm then maybe we can help you write one, but if scipy already has it then just use 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 oscar.j.benjamin at gmail.com Fri Oct 2 22:39:35 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Fri, 02 Oct 2015 20:39:35 +0000 Subject: [Tutor] How to calculate the cumulative normal distribution In-Reply-To: <201509300913.t8U9D4Ix008998@fido.openend.se> References: <571CF484-76E2-4289-840D-5892DE4096AD@yahoo.co.uk> <201509300913.t8U9D4Ix008998@fido.openend.se> Message-ID: On Wed, 30 Sep 2015 10:14 Laura Creighton wrote: In a message of Wed, 30 Sep 2015 09:12:20 +0300, Michel Guirguis writes: >Good afternoon, > >How to calculate the cumulative normal distribution function CND in order to use this figure to calculate the call option based on the Black and Scholes model. The easy way is to install scipy Michel, It sounds like you probably do want to install scipy for the work that you're doing and Laura's correct that anaconda is the easiest way to do that. However I want to point out that your specific problem is easily solved with the stdlib. The CDF of the standard normal distribution is easily expressed in terms of the error function erf which is available in the math module: fron math import erf def phi(z): return 0.5 * (1 + erf(z)) -- Oscar From jrod115683 at yahoo.com Fri Oct 2 18:41:09 2015 From: jrod115683 at yahoo.com (Jared Johnson) Date: Fri, 2 Oct 2015 16:41:09 +0000 (UTC) Subject: [Tutor] Quick Programming Question Message-ID: <1561085325.334250.1443804069198.JavaMail.yahoo@mail.yahoo.com> I've been stuck on this for a while now and was wondering if you could help. The question is: "A pentagonal number is defined as n(3n - 1)/2 for n = 1,2 etc. So, the first few numbers are 1, 5, 12, 22 etc. Write a function with the following header that returns a pentagonal number: def getPentagonalNumber(n): Write a test program that uses this function to display the first 100 pentagonal numbers with 10 numbers on each line." I am very new at programming and if you could help me out at all by putting this is the simplest terms, that would be extremely helpful! Thanks! From anshu.kumar726 at gmail.com Fri Oct 2 18:52:28 2015 From: anshu.kumar726 at gmail.com (Anshu Kumar) Date: Fri, 2 Oct 2015 22:22:28 +0530 Subject: [Tutor] Mutable data type in python Message-ID: Hi Everyone, I have been facing this problem from a while in python could I please be helped? When we invoke the same function inside a function (recursive function), i want to keep track of some data across all function invocation so i should have shareable type but built in data types string, int are not helping as they are immutable they are changed while next invocation. I could use lists which are mutable but sometimes i find it not suitable for example when i need only single number or string. Thanks and Regards, Anshu From nymcity at yahoo.com Sat Oct 3 00:57:15 2015 From: nymcity at yahoo.com (Nym City) Date: Fri, 2 Oct 2015 22:57:15 +0000 (UTC) Subject: [Tutor] Exception Handling Message-ID: <77090306.483942.1443826635262.JavaMail.yahoo@mail.yahoo.com> Hello, I am trying to get IP addresses for about 500 public domains but I think for some where resolution is not available - my exception handling breaks the code.? To troubleshoot, I added several Print statements to see what I was getting and it looks like my blank list is getting populated with domain names just fine and it starts to resolve addresses but less than half way though it errors out with the following message: Traceback (most recent call last): ? File "C:/Users/Documents/Python/MyProject/HostnameResolution/HostnameResolution.py", line 15, in ??? ResolveHostname = socket.gethostbyname(name) socket.gaierror: [Errno 11004] getaddrinfo failed Here is the Code: import socket ListOfHostNames = [] with open('hostnames.csv', 'r') as f: ??? for line in f: ??????? line = line.strip() ??????? ListOfHostNames.append(line) newFile = open('hostnames.csv', 'w') print(ListOfHostNames) for name in ListOfHostNames: ??? try: ??????? ResolveHostname = socket.gethostbyname(name) ??????? print(ResolveHostname) ??????? newFile.write(ResolveHostname + "\n") ??????? print(ResolveHostname) ??? except socket.herror as e: ??????? newFile.write("No resolution available for %s" % (name) + "\n") newFile.close() Please advice. Thanks!?Thank you. From alan.gauld at btinternet.com Sat Oct 3 01:35:56 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 3 Oct 2015 00:35:56 +0100 Subject: [Tutor] Mutable data type in python In-Reply-To: References: Message-ID: On 02/10/15 17:52, Anshu Kumar wrote: > When we invoke the same function inside a function (recursive function), i > want to keep track of some data across all function invocation so i should > have shareable type but built in data types string, int are not helping as > they are immutable they are changed while next invocation. Show us some code and we will understand exactly what you are struggling with. I think I know, but it would be easier if you give a specific short example. > I could use lists which are mutable but sometimes i find it not suitable > for example when i need only single number or string. You can create a closure using a list, or you could use a global or you could just use a lot of parameters/return values. But without seeing exactly what you are trying to do its difficult to know which options suit you best. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Sat Oct 3 01:42:51 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 3 Oct 2015 00:42:51 +0100 Subject: [Tutor] Quick Programming Question In-Reply-To: <1561085325.334250.1443804069198.JavaMail.yahoo@mail.yahoo.com> References: <1561085325.334250.1443804069198.JavaMail.yahoo@mail.yahoo.com> Message-ID: On 02/10/15 17:41, Jared Johnson via Tutor wrote: > "A pentagonal number is defined as > n(3n - 1)/2 for n = 1,2 etc. > Write a function with the following header that returns a pentagonal number: > def getPentagonalNumber(n): It's asking you to write a function that returns the result of the equation. Here is a simpler example Write a function with the following header that returns a squared number: def getSquare(n): And the solution looks like: def getSquare(n): return n*n You need something similar for your pentagonal numbers. > Write a test program that uses this function to display the > first 100 pentagonal numbers with 10 numbers on each line." I assume you know how to use for loops? This is just a nested for loop. The outer for the 10 lines and the inner for the 10 values per line If you need more help then reply explaining which bits you are confused about and we can break it down further. Note: as policy we do not provide solutions to homeworks but we will give suggestions/hints etc. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Sat Oct 3 01:51:37 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 3 Oct 2015 00:51:37 +0100 Subject: [Tutor] Exception Handling In-Reply-To: <77090306.483942.1443826635262.JavaMail.yahoo@mail.yahoo.com> References: <77090306.483942.1443826635262.JavaMail.yahoo@mail.yahoo.com> Message-ID: On 02/10/15 23:57, Nym City via Tutor wrote: > socket.gaierror: [Errno 11004] getaddrinfo failed ... > for name in ListOfHostNames: > try: > ResolveHostname = socket.gethostbyname(name) > print(ResolveHostname) > newFile.write(ResolveHostname + "\n") > print(ResolveHostname) > except socket.herror as e: > newFile.write("No resolution available for %s" % (name) + "\n") You are catching herror but your code is resulting in gaierror. Add socket.gaierror to your except line. except (socket.herror, socket.gaierror): newFile.write("No resolution available for %s" % (name) + "\n") see if that works -- 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 Sat Oct 3 05:49:13 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 3 Oct 2015 13:49:13 +1000 Subject: [Tutor] Exception Handling In-Reply-To: References: Message-ID: <20151003034913.GA23567@cskk.homeip.net> On 03Oct2015 00:51, ALAN GAULD wrote: >On 02/10/15 23:57, Nym City via Tutor wrote: >>socket.gaierror: [Errno 11004] getaddrinfo failed >... >>for name in ListOfHostNames: >> try: >> ResolveHostname = socket.gethostbyname(name) >> print(ResolveHostname) >> newFile.write(ResolveHostname + "\n") >> print(ResolveHostname) >> except socket.herror as e: >> newFile.write("No resolution available for %s" % (name) + "\n") > >You are catching herror but your code is resulting in gaierror. > >Add socket.gaierror to your except line. > > except (socket.herror, socket.gaierror): > newFile.write("No resolution available for %s" % (name) + "\n") > >see if that works Just a followon remark: always try to print the exception when you're not certain of what it will be or what to do with it. So I'd augument Alan's code like this: except (socket.herror, socket.gaierror) as e: newFile.write("No resolution available for %s: %s" % (name, e) + "\n") Cheers, Cameron Simpson From cs at zip.com.au Sat Oct 3 07:09:09 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sat, 3 Oct 2015 15:09:09 +1000 Subject: [Tutor] Mutable data type in python In-Reply-To: References: Message-ID: <20151003050909.GA47595@cskk.homeip.net> On 02Oct2015 22:22, Anshu Kumar wrote: >When we invoke the same function inside a function (recursive function), i >want to keep track of some data across all function invocation so i should >have shareable type but built in data types string, int are not helping as >they are immutable they are changed while next invocation. > >I could use lists which are mutable but sometimes i find it not suitable >for example when i need only single number or string. Please provide some more context, perhaps with an example of what you're trying to do. What follows is general advice which may not be what you need. Anyway... What you use depends very much on what you need (trite, but true). Numbers and strings are not themselfs mutable. I'm presuming you want some kind of shared state that continues over the recursion, for example a record of what nodes have already been visiting while traversing a graph with loops: if you follow a loop you want to stop instead of circling/recursing forever. When I do this I usually form the function somewhat like the below. Let's suppose we're walking a graph whose nodes have a ".children" attribute which is a list of child nodes. And that the graph might have loops (this node might be a child or subchild of itself). def traverse(node, seen=None): ''' Traverse the graph from `node`, printing each node's name. `seen`: if not None, a set of nodes already visited. ''' if seen is None: seen = set() seen.add(node) print(node.name) for child in node.children: if child not in seen: traverse(child, seen) So the paramater "seen" is your mutable object keeping track of which nodes have been visited. You add this node to "seen", then visit any children which are not in "seen". You pass "seen" to the traverse() of each child, so all the function calls share the same "seen" object. So in this case we're using a set. There's any number of different things you might use depending on what you need to keep track of. Cheers, Cameron Simpson From anshu.kumar726 at gmail.com Sat Oct 3 04:46:50 2015 From: anshu.kumar726 at gmail.com (Anshu Kumar) Date: Sat, 3 Oct 2015 08:16:50 +0530 Subject: [Tutor] Mutable data type in python In-Reply-To: References: Message-ID: Hi Alan, I was trying to solve a simple dynamic programming problem. It goes like this. I have an input integer and i can choose to divide it by two or three or subtract by one to reduce it to one. there is a condition the number has to be divisible by 2 or 3 if we are dividing by two or three respectively. I have to get shortest path to reduce input number to 1 by using combination of either divide by three or two or subtract one. so let suppose i have number 16 as input it will be reduced to 1 in 5 number of minimal steps 16-->16-1 = 15 -->15/3 = 5-->5-1= 4--> 4/2=2-->2/2 =1 so i wrote a simple program like this depth = float('inf') def findMinDepthPath(n,counter): global depth if(n== 1 and counter < depth): depth = counter elif(( n==2 or n==3) and counter < depth): depth = counter + 1 else: if(counter < depth): if(n%3 == 0): findMinDepthPath(n/3,counter + 1) if(n%2 == 0): findMinDepthPath(n/2,counter + 1) findMinDepthPath(n-1,counter +1) def getMinDepthPathLength(n): global depth depth = float('inf') findMinDepthPath(n,0) return depth it works fine with global variable or a list type parameter for depth but i am looking for a way where i would be able to use a parameter which will be shared across all invocation and it should certainly not be a list coz i don't need a list Thanks and appreciate your help, Anshu On Sat, Oct 3, 2015 at 5:05 AM, Alan Gauld wrote: > On 02/10/15 17:52, Anshu Kumar wrote: > > When we invoke the same function inside a function (recursive function), i >> want to keep track of some data across all function invocation so i should >> have shareable type but built in data types string, int are not helping as >> they are immutable they are changed while next invocation. >> > > Show us some code and we will understand exactly what you are struggling > with. I think I know, but it would be easier if > you give a specific short example. > > I could use lists which are mutable but sometimes i find it not suitable >> for example when i need only single number or string. >> > > You can create a closure using a list, or you could use a global > or you could just use a lot of parameters/return values. But > without seeing exactly what you are trying to do its difficult > to know which options suit you best. > > > -- > 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 btinternet.com Sat Oct 3 10:02:47 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 3 Oct 2015 09:02:47 +0100 Subject: [Tutor] Mutable data type in python In-Reply-To: References: Message-ID: On 03/10/15 03:46, Anshu Kumar wrote: > Hi Alan, > > I was trying to solve a simple dynamic programming problem. > > It goes like this. I have an input integer and i can choose to divide it by > two or three or subtract by one to reduce it to one. there is a condition > the number has to be divisible by 2 or 3 if we are dividing by two or three > respectively. I have to get shortest path to reduce input number to 1 by > using combination of either divide by three or two or subtract one. > > > so let suppose i have number 16 as input it will be reduced to 1 in 5 > number of minimal steps 16-->16-1 = 15 -->15/3 = 5-->5-1= 4--> 4/2=2-->2/2 > =1 I donm;t understand the logic. I'd have expected 16/2->8 as the first step, then 8/2 etc. So the depth would be 4? Why would n-1 be the first step? And your code below certainly doesn't do that. In fact it calls n-1 on every iteration. > depth = float('inf') > > def findMinDepthPath(n,counter): > global depth > if(n== 1 and counter < depth): > depth = counter > elif(( n==2 or n==3) and counter < depth): > depth = counter + 1 > else: > if(counter < depth): > if(n%3 == 0): > findMinDepthPath(n/3,counter + 1) > if(n%2 == 0): > findMinDepthPath(n/2,counter + 1) > findMinDepthPath(n-1,counter +1) If I understand what I think you want I'd write this as: def findMinDepthPath(n): if n== 1: return 0 elif n==2 or n==3: return 1 elif n%3 == 0: return findMinDepthPath(n/3)+1 elif n%2 == 0: return findMinDepthPath(n/2)+1 else: return findMinDepthPath(n-1)+1 The key difference being that I return a value rather than try to set an external one. That removes the need for the depth and counter values. But it does give different results to your code because the algorithm is slightly different for the n-1 cases, so I may be oversimplifying. If so please explain the logic again. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From lac at openend.se Sat Oct 3 11:02:07 2015 From: lac at openend.se (Laura Creighton) Date: Sat, 03 Oct 2015 11:02:07 +0200 Subject: [Tutor] Mutable data type in python In-Reply-To: References: Message-ID: <201510030902.t939273a002098@fido.openend.se> >it works fine with global variable or a list type parameter for depth but i >am looking for a way where i would be able to use a parameter which will be >shared across all invocation and it should certainly not be a list coz i >don't need a list > >Thanks and appreciate your help, >Anshu I am not sure what you mean 'shared across all invocation'. You have a room of computers, and they all are going to use this program to find solutions, and you don't want them to duplicate work? This thing runs for a very long time and I want to be able to stop running this program .. have my laptop crash, even ... and start it up and have it pick up where it left off the last time? If this is your problem, then even lists and global variables will not help you, and you really need to save the data you need out on disk someplace. This leads me to believe that I just don't understand you properly yet. Laura From anshu.kumar726 at gmail.com Sat Oct 3 10:23:19 2015 From: anshu.kumar726 at gmail.com (Anshu Kumar) Date: Sat, 3 Oct 2015 13:53:19 +0530 Subject: [Tutor] Mutable data type in python In-Reply-To: References: Message-ID: Hi Alan, I have given a wrong example of 16 . I am sorry for it. You are correct it will take only 4 turns. If i consider your solution for number 10 it will go like this 10-->10/2 =5 --> 5-1=4--> 4/2 =2-->2/2 =1 which gives 4 as output but answer would be in 3 steps 10-->10-1=9-->9/3=3-->3/3=1 So we must consider every path /3, /2 and -1 and try to find out shortest one which i tested with my logic it works because I have put multiple recursive calls to span multiple branches. I am certain with my logic as it passes most of test cases. Due to multiple branches it takes more time for large numbers but returns correct result. I have used global variable called depth but was wondering if we can have something being passed as function parametedata structurr which could have been shared across all invocations. I know list and sets can be used do we have any other data structure in python which would be mutable and not a sequence? Thanks and appreciate your generous help, Anshu On Sat, Oct 3, 2015 at 1:32 PM, Alan Gauld wrote: > On 03/10/15 03:46, Anshu Kumar wrote: > >> Hi Alan, >> >> I was trying to solve a simple dynamic programming problem. >> >> It goes like this. I have an input integer and i can choose to divide it >> by >> two or three or subtract by one to reduce it to one. there is a condition >> the number has to be divisible by 2 or 3 if we are dividing by two or >> three >> respectively. I have to get shortest path to reduce input number to 1 by >> using combination of either divide by three or two or subtract one. >> >> >> so let suppose i have number 16 as input it will be reduced to 1 in 5 >> number of minimal steps 16-->16-1 = 15 -->15/3 = 5-->5-1= 4--> 4/2=2-->2/2 >> =1 >> > > I donm;t understand the logic. > I'd have expected 16/2->8 as the first step, then 8/2 etc. So the depth > would be 4? Why would n-1 be the first step? And your code below certainly > doesn't do that. In fact it calls n-1 on every iteration. > > > depth = float('inf') >> >> def findMinDepthPath(n,counter): >> global depth >> if(n== 1 and counter < depth): >> depth = counter >> elif(( n==2 or n==3) and counter < depth): >> depth = counter + 1 >> else: >> if(counter < depth): >> if(n%3 == 0): >> findMinDepthPath(n/3,counter + 1) >> if(n%2 == 0): >> findMinDepthPath(n/2,counter + 1) >> findMinDepthPath(n-1,counter +1) >> > > If I understand what I think you want I'd write this as: > > def findMinDepthPath(n): > if n== 1: > return 0 > elif n==2 or n==3: > return 1 > elif n%3 == 0: > return findMinDepthPath(n/3)+1 > elif n%2 == 0: > return findMinDepthPath(n/2)+1 > else: > return findMinDepthPath(n-1)+1 > > The key difference being that I return a value rather > than try to set an external one. That removes the need > for the depth and counter values. > > But it does give different results to your code because > the algorithm is slightly different for the n-1 cases, > so I may be oversimplifying. If so please explain the > logic again. > > > -- > 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 btinternet.com Sat Oct 3 14:28:34 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 3 Oct 2015 13:28:34 +0100 Subject: [Tutor] Mutable data type in python In-Reply-To: References: Message-ID: <560FC9F2.4070102@btinternet.com> On 03/10/15 09:23, Anshu Kumar wrote: > Hi Alan, > > I have given a wrong example of 16 . I am sorry for it. You are > correct it will take only 4 turns. > > If i consider your solution for number 10 > > it will go like this 10-->10/2 =5 --> 5-1=4--> 4/2 =2-->2/2 =1 which > gives 4 as output but answer would be in 3 steps > 10-->10-1=9-->9/3=3-->3/3=1 > > So we must consider every path /3, /2 and -1 and try to find out > shortest one Ah, OK I see. Here is my modified version which I think works as you want: def findMinDepthPath(n): if n <= 0: raise ValueError elif n==1: return 0 elif n==2 or n==3: return 1 else: d1 = findMinDepthPath(n-1)+1 d2 = d3 = (d1+1) # initialize to higher than d1 if n%3 == 0: d3 = findMinDepthPath(n/3)+1 if n%2 == 0: d2 = findMinDepthPath(n/2)+1 return min(d1,d2,d3) n = int(raw_input('N? ')) print "Minimum depth = ", findMinDepthPath(n),'\n' >I know list and sets can be used do we have any other data structure in python > which would be mutable and not a sequence? You could use a dictionary but that is also a type of sequence... So a class is the obvious non-sequential candidate. class Store: def __init__(self, value = 0): self.value = value You can then pass an instance of the class and modify its value. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From lac at openend.se Sat Oct 3 14:59:14 2015 From: lac at openend.se (Laura Creighton) Date: Sat, 03 Oct 2015 14:59:14 +0200 Subject: [Tutor] Mutable data type in python In-Reply-To: References: Message-ID: <201510031259.t93CxEEM019925@fido.openend.se> One thing you can do is to make your variable live in another module. This is a common way to make config files, for instance. say you have a file called config.py which contains the single line my_int = 0 then in your main program you can do: import config and start using config.my_int wherever you would like to. of course, you can also do from config import my_int and start using my_int At this point, you aren't any better off that just using a global, though. Note that if you do: config.my_int = 1 or my_int = 1 the file config.py is not changed. The next time anybody imports it, they will get the 0 value for my_int. Laura From illusiontechniques at gmail.com Sat Oct 3 20:10:27 2015 From: illusiontechniques at gmail.com (C Smith) Date: Sat, 3 Oct 2015 11:10:27 -0700 Subject: [Tutor] Mutable data type in python In-Reply-To: <560FC9F2.4070102@btinternet.com> References: <560FC9F2.4070102@btinternet.com> Message-ID: > Here is my modified version which I think works as you want: > > def findMinDepthPath(n): > if n <= 0: raise ValueError > elif n==1: > return 0 > elif n==2 or n==3: > return 1 > else: > d1 = findMinDepthPath(n-1)+1 > d2 = d3 = (d1+1) # initialize to higher than d1 > > if n%3 == 0: > d3 = findMinDepthPath(n/3)+1 > if n%2 == 0: > d2 = findMinDepthPath(n/2)+1 > > return min(d1,d2,d3) > > > n = int(raw_input('N? ')) > print "Minimum depth = ", findMinDepthPath(n),'\n' Doesn't this only look one level deep? Is the poster asking for something that would traverse all possible paths and then check for the shortest? From alan.gauld at btinternet.com Sat Oct 3 20:55:56 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 3 Oct 2015 19:55:56 +0100 Subject: [Tutor] Mutable data type in python In-Reply-To: References: <560FC9F2.4070102@btinternet.com> Message-ID: <561024BC.10402@btinternet.com> On 03/10/15 19:10, C Smith wrote: >> Here is my modified version which I think works as you want: >> >> def findMinDepthPath(n): >> if n <= 0: raise ValueError >> elif n==1: >> return 0 >> elif n==2 or n==3: >> return 1 >> else: >> d1 = findMinDepthPath(n-1)+1 >> d2 = d3 = (d1+1) # initialize to higher than d1 >> >> if n%3 == 0: >> d3 = findMinDepthPath(n/3)+1 >> if n%2 == 0: >> d2 = findMinDepthPath(n/2)+1 >> >> return min(d1,d2,d3) >> >> >> n = int(raw_input('N? ')) >> print "Minimum depth = ", findMinDepthPath(n),'\n' > Doesn't this only look one level deep? Is the poster asking for > something that would traverse all possible paths and then check for > the shortest? No, this is a recursive function which keeps calling itself with smaller values of n until it reaches 1-3, at which point it returns a known result. Here is an example of the factorial() function written recursively in a similar style, it might be easier to see how it works: def square(n): print n # show the recursion if n <= 1: return 1 else: return n * factorial(n-1) print factorial(5) 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 nymcity at yahoo.com Sat Oct 3 20:17:20 2015 From: nymcity at yahoo.com (Nym City) Date: Sat, 3 Oct 2015 18:17:20 +0000 (UTC) Subject: [Tutor] Exception Handling In-Reply-To: <20151003034913.GA23567@cskk.homeip.net> References: <20151003034913.GA23567@cskk.homeip.net> Message-ID: <944372268.714085.1443896240354.JavaMail.yahoo@mail.yahoo.com> Thank you (Cameron and Alan) for your review and feedback. This solved the issue perfectly! ?Thank you. On Friday, October 2, 2015 11:49 PM, Cameron Simpson wrote: On 03Oct2015 00:51, ALAN GAULD wrote: >On 02/10/15 23:57, Nym City via Tutor wrote: >>socket.gaierror: [Errno 11004] getaddrinfo failed >... >>for name in ListOfHostNames: >>? ? try: >>? ? ? ? ResolveHostname = socket.gethostbyname(name) >>? ? ? ? print(ResolveHostname) >>? ? ? ? newFile.write(ResolveHostname + "\n") >>? ? ? ? print(ResolveHostname) >>? ? except socket.herror as e: >>? ? ? ? newFile.write("No resolution available for %s" % (name) + "\n") > >You are catching herror but your code is resulting in gaierror. > >Add socket.gaierror to your except line. > >? ? except (socket.herror, socket.gaierror): >? ? ? ? newFile.write("No resolution available for %s" % (name) + "\n") > >see if that works Just a followon remark: always try to print the exception when you're not certain of what it will be or what to do with it. So I'd augument Alan's code like this: ? ? except (socket.herror, socket.gaierror) as e: ? ? ? ? newFile.write("No resolution available for %s: %s" % (name, e) + "\n") Cheers, Cameron Simpson _______________________________________________ Tutor maillist? -? Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From illusiontechniques at gmail.com Sun Oct 4 00:20:31 2015 From: illusiontechniques at gmail.com (C Smith) Date: Sat, 3 Oct 2015 15:20:31 -0700 Subject: [Tutor] Mutable data type in python In-Reply-To: <561024BC.10402@btinternet.com> References: <560FC9F2.4070102@btinternet.com> <561024BC.10402@btinternet.com> Message-ID: On Sat, Oct 3, 2015 at 11:55 AM, Alan Gauld wrote: > On 03/10/15 19:10, C Smith wrote: >>> >>> Here is my modified version which I think works as you want: >>> >>> def findMinDepthPath(n): >>> if n <= 0: raise ValueError >>> elif n==1: >>> return 0 >>> elif n==2 or n==3: >>> return 1 >>> else: >>> d1 = findMinDepthPath(n-1)+1 >>> d2 = d3 = (d1+1) # initialize to higher than d1 >>> >>> if n%3 == 0: >>> d3 = findMinDepthPath(n/3)+1 >>> if n%2 == 0: >>> d2 = findMinDepthPath(n/2)+1 >>> >>> return min(d1,d2,d3) >>> >>> What I meant was that the algorithm assumes that the lowest value from one "action" (minus one, divide by 2, divide by 3) is the best possible branch in the tree. That seems intuitively correct, but is it necessarily so? From alan.gauld at btinternet.com Sun Oct 4 01:13:27 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 4 Oct 2015 00:13:27 +0100 Subject: [Tutor] Mutable data type in python In-Reply-To: References: <560FC9F2.4070102@btinternet.com> <561024BC.10402@btinternet.com> Message-ID: <56106117.3010403@btinternet.com> On 03/10/15 23:20, C Smith wrote: > On Sat, Oct 3, 2015 at 11:55 AM, Alan Gauld wrote: >> On 03/10/15 19:10, C Smith wrote: >>>> Here is my modified version which I think works as you want: >>>> >>>> def findMinDepthPath(n): >>>> if n <= 0: raise ValueError >>>> elif n==1: >>>> return 0 >>>> elif n==2 or n==3: >>>> return 1 >>>> else: >>>> d1 = findMinDepthPath(n-1)+1 >>>> d2 = d3 = (d1+1) # initialize to higher than d1 >>>> >>>> if n%3 == 0: >>>> d3 = findMinDepthPath(n/3)+1 >>>> if n%2 == 0: >>>> d2 = findMinDepthPath(n/2)+1 >>>> >>>> return min(d1,d2,d3) > What I meant was that the algorithm assumes that the lowest value from > one "action" (minus one, divide by 2, divide by 3) is the best > possible branch in the tree. That seems intuitively correct, but is it > necessarily so? I see. The answer is I don't know mathematically speaking. But I figured that the minimum path for (n-1|n/2|n/3) plus 1 must be the minimum path for n. But that was an entirely inuitive assumption. Also because the minimum path is being figured from the bottom to the top - ie it finds the minimum path for 1..3 first, then for 4 via n/2 then 5 via n-1 and so on. It *feels* like that it should always select the minimum path. But I have learnt that in math intuitive is not always right :-) So if anyone can mathematically prove my hunch right or wrong that would be interesting... -- 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 richkappler at gmail.com Mon Oct 5 19:46:52 2015 From: richkappler at gmail.com (richard kappler) Date: Mon, 5 Oct 2015 13:46:52 -0400 Subject: [Tutor] general exception questions Message-ID: I'm reading up on exception handling, and am a little confused. If you have an exception that just has 'pass' in it, for example in a 'for line in file:' iteration, what happens? Does the program just go to the next line? EX: for line in file: try: do something except: pass I know (so many of you have told me :-) that using pass is a bad idea, but how else do you skip the current line if the 'try' can't be done, and go on to the next line exiting the program with a trace error? regards, Richard From alan.gauld at btinternet.com Mon Oct 5 20:11:27 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 5 Oct 2015 19:11:27 +0100 Subject: [Tutor] general exception questions In-Reply-To: References: Message-ID: On 05/10/15 18:46, richard kappler wrote: > I'm reading up on exception handling, and am a little confused. If you have > an exception that just has 'pass' in it, for example in a 'for line in > file:' iteration, what happens? Does the program just go to the next line? Yes, in your example it would ignore the exception and just move on to the next line. Using continue would do the same and be more explicit. If you do want to stop the loop use break. > EX: > > for line in file: > try: > do something > except: > pass > > I know (so many of you have told me :-) that using pass is a bad idea, Not necessarily, pass is fine in many situations. The only problem is in situations where it's not needed at all - then its better to just simplify the construct. For example: if some_test(): do_something() else: pass is better written as just if some_test(): do_something() But something like: class MyNewException(Exception): pass is absolutely OK. > how else do you skip the current line if the 'try' can't be done, and go on > to the next line exiting the program with a trace error? That last sentence confused me. If you use pass (or continue) you will NOT get any trace error. If you want to store the error to report it at the end then it's quite a bit more work, you would need something like: errors = [] for line in file: try: process(line) except SomeError as e: errors.append((line,e)) if errors: for e in errors: display_error(e) where display_error() is an exercise for the student :-) 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 richkappler at gmail.com Mon Oct 5 20:23:39 2015 From: richkappler at gmail.com (richard kappler) Date: Mon, 5 Oct 2015 14:23:39 -0400 Subject: [Tutor] general exception questions In-Reply-To: References: Message-ID: > > > > how else do you skip the current line if the 'try' can't be done, and go on >> to the next line exiting the program with a trace error? >> > > That last sentence confused me. If you use pass (or continue) > you will NOT get any trace error. If you want to store the > error to report it at the end then it's quite a bit more work, > you would need something like: > Yup, confused myself when I reread it, sorry Alan. It should have been ..if the 'try' can't be done, and go on to the next line INSTEAD OF exiting the program with a trace error. > > errors = [] > for line in file: > try: > process(line) > except SomeError as e: > errors.append((line,e)) > > if errors: > for e in errors: > display_error(e) > > where display_error() is an exercise for the student :-) > Interesting. Sounds like something else I need to take a round turn on. regards, Richard From alan.gauld at btinternet.com Mon Oct 5 20:38:15 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 5 Oct 2015 19:38:15 +0100 Subject: [Tutor] Fwd: Re: IDLE: Integrated Development and Learning Environment? In-Reply-To: References: Message-ID: <5612C397.5090300@btinternet.com> I thought this might be of interest to the tutor community. IDLE gets a new definition (with Guido's approval)... Also he explains why its IDLE and not Idle. The definition has now changed from: Integrated DeveLopment Environment to Integrated Development and Learning Environment Partly to reflect several funky new features being added to help Learners. The top posting(shock!) is by Guido so not my fault! ;-) Alan G -------- Forwarded Message -------- Subject: Re: IDLE: Integrated Development and Learning Environment? Date: Fri, 2 Oct 2015 17:16:42 -0700 From: Guido van Rossum Reply-To: guido at python.org To: Terry Reedy CC: idle Newsgroups: gmane.comp.python.idle References: <560EF3E2.1060300 at udel.edu> <560F0C5F.4030602 at udel.edu> I think I was reluctant to name it after a living person. I like the idea of keeping it all caps and changing the interpretation. On Fri, Oct 2, 2015 at 3:59 PM, Terry Reedy > wrote: On 10/2/2015 6:45 PM, Guido van Rossum wrote: I like it. Though of course it's really named after Eric Idle. :-) Until a couple of days ago, I was planning to propose changing 'IDLE' to 'Idle', which is what I have writen.? I am willing to go with that change instead.? But I presumed that you must have preferred the all-caps version, or perhaps not directly naming it after Eric, and then I thought of how to make 'IDLE' an informative acronym rather than a clumbsy semi-acronyn.? So now I prefer to change the interpretation than the spelling. -- Terry Jan Reedy -- --Guido van Rossum (python.org/~guido ) -------------- next part -------------- _______________________________________________ IDLE-dev mailing list IDLE-dev at python.org https://mail.python.org/mailman/listinfo/idle-dev From breamoreboy at yahoo.co.uk Mon Oct 5 23:39:13 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 5 Oct 2015 22:39:13 +0100 Subject: [Tutor] general exception questions In-Reply-To: References: Message-ID: On 05/10/2015 18:46, richard kappler wrote: > I'm reading up on exception handling, and am a little confused. If you have > an exception that just has 'pass' in it, for example in a 'for line in > file:' iteration, what happens? Does the program just go to the next line? > > EX: > > for line in file: > try: > do something > except: > pass > > I know (so many of you have told me :-) that using pass is a bad idea, but > how else do you skip the current line if the 'try' can't be done, and go on > to the next line exiting the program with a trace error? > > regards, Richard Don't put the `try: except:` there in the first place. This is the best way to approach development. Let Python throw all your programming errors at you, then refine your code to catch the ones you need to. See https://docs.python.org/3/library/exceptions.html#exception-hierarchy for the ones you would potentially need to catch for file handling under OSError. One must also add the obligatory never use a bare `except:` -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From lac at openend.se Tue Oct 6 00:13:06 2015 From: lac at openend.se (Laura Creighton) Date: Tue, 06 Oct 2015 00:13:06 +0200 Subject: [Tutor] general exception questions In-Reply-To: References: Message-ID: <201510052213.t95MD68Y014240@fido.openend.se> In a message of Mon, 05 Oct 2015 22:39:13 +0100, Mark Lawrence writes: >On 05/10/2015 18:46, richard kappler wrote: >> I'm reading up on exception handling, and am a little confused. If you have >> an exception that just has 'pass' in it, for example in a 'for line in >> file:' iteration, what happens? Does the program just go to the next line? >> >> EX: >> >> for line in file: >> try: >> do something >> except: >> pass >> >> I know (so many of you have told me :-) that using pass is a bad idea, but >> how else do you skip the current line if the 'try' can't be done, and go on >> to the next line exiting the program with a trace error? >> >> regards, Richard > >Don't put the `try: except:` there in the first place. This is the best >way to approach development. Let Python throw all your programming >errors at you, then refine your code to catch the ones you need to. See >https://docs.python.org/3/library/exceptions.html#exception-hierarchy >for the ones you would potentially need to catch for file handling under >OSError. > >One must also add the obligatory never use a bare `except:` > >-- >My fellow Pythonistas, ask not what our language can do for you, ask >what you can do for our language. > >Mark Lawrence I think this depends on what the script is doing. For commerical, production use you generally want to find out what the errors are and do something reasonable for them -- but for my own use there are plenty of times when I want to run this thing once. If it runs into trouble I want it to keep on trying to do its thing. The only thing I might consider doing with any exceptions that get raised is logging them before ignoring them. The worst thing that could happen is for the script to quit running after a few hours because some wretched exception I wasn't ready for happened. This means I will have to add that exception to the list of things to ignore and run the thing again next night ... Laura From steve at pearwood.info Tue Oct 6 03:29:24 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 6 Oct 2015 12:29:24 +1100 Subject: [Tutor] general exception questions In-Reply-To: References: Message-ID: <20151006012924.GW23642@ando.pearwood.info> On Mon, Oct 05, 2015 at 01:46:52PM -0400, richard kappler wrote: > I'm reading up on exception handling, and am a little confused. If you have > an exception that just has 'pass' in it, for example in a 'for line in > file:' iteration, what happens? Does the program just go to the next line? Yes. The exception is caught and then processing continues in the usual manner from the except clause. In your example below, that would mean returning to the start of the for-loop. > EX: > > for line in file: > try: > do something > except: > pass > > I know (so many of you have told me :-) that using pass is a bad idea *scratches head* I don't remember anyone saying that *pass* itself if a bad idea. On it's own, pass just tells the Python compiler to do nothing. But what *really is* a bad idea is the bare "except" sitting there like a land mine, waiting to blow up in your face. Bare excepts have their uses, their *very rare* uses, but in general what they mostly do is hide bugs and make them much harder to fix. https://realpython.com/blog/python/the-most-diabolical-python-antipattern/ What *may* be a bad idea is the "do something" inside a try clause -- it's hard to tell, without knowing what "do something" actually is. try...except blocks are great, they are an extremely powerful and useful part of the Python programming language. But they are easy to misuse. Here are two simple rules for effectively and safely using try...except: (1) Put the *least amount of code possible* inside the try. (2) Catch the *fewest number of exceptions* possible in the except. If you remember those two rules, your try...except blocks will be much less likely to bite. You should protect the least amount of code as you can inside the try. For example, this is probably a bad idea: try: i = mylist.index("") del other[i + START] process(mylist) except ValueError: # tag not found handle_missing_tag() The *intention* is to catch the ValueError that is raised by index() when "" is not found, but in fact there are four different places where ValueError could, potentially, be raised: - the call to index() - the calculation of i + START - the del start[...] - the function call process(...) Only in the first case is ValueError expected, and can be safely caught and handled. In the other three places, a ValueError would be totally unexpected, and would indicate a bug that needs to be fixed. To fix the bug, you would need to see it in the first case, and you can't see it if it is caught and suppressed by the try...except. This would probably be better written like this: try: i = mylist.index("") except ValueError: # tag not found handle_missing_tag() else: del other[i + START] process(mylist) or similar. Inside a function, you might do this: def func(): try: i = mylist.index("") except ValueError: # tag not found handle_missing_tag() return del other[i + START] process(mylist) Now, if process() raises ValueError, you will see it, and can fix the bug. Of course, there are times where being lazy is a virtue: for x in sequence: try: process(x) except Exception: pass is fine in the interactive interpreter, where you don't care about best practices, reliability, long-term maintainability, etc. You don't really care what goes wrong, you just want to keep going no matter what. But notice that I've caught Exception, rather than a bare except. I've done that so that I can interrupt the script and cancel processing with Ctrl-C, otherwise the KeyboardInterrupt exception will be caught and ignored too! But even in this case, the quick-n-dirtiest of the quick-n-dirty scripts, there's a significant risk of failure: for x in sequence: try: proces(x) # Oops, typo. except Exception: pass I have done this: intending to process a long list, I fired off the script, then came back an hour or two later only to discover that it had done *absolutely nothing* due to a silly typo. -- Steve From wolf.halton at gmail.com Tue Oct 6 04:20:08 2015 From: wolf.halton at gmail.com (Wolf Halton) Date: Mon, 5 Oct 2015 22:20:08 -0400 Subject: [Tutor] Fwd: Re: IDLE: Integrated Development and Learning Environment? In-Reply-To: <5612C397.5090300@btinternet.com> References: <5612C397.5090300@btinternet.com> Message-ID: <5B38E75D-D92E-4DD9-8816-CE32F2C7A10C@gmail.com> That is informative. I am glad the acronym is de-kluged. Wolf Halton Atlanta Cloud Technology Business Continuity Solutions 678-687-6104 -- Sent from my iPhone. Creative word completion courtesy of Apple, Inc. > On Oct 5, 2015, at 2:38 PM, Alan Gauld wrote: > > I thought this might be of interest to the tutor community. > > IDLE gets a new definition (with Guido's approval)... > Also he explains why its IDLE and not Idle. > > The definition has now changed from: > > Integrated DeveLopment Environment > to > Integrated Development and Learning Environment > > Partly to reflect several funky new features being added > to help Learners. > > The top posting(shock!) is by Guido so not my fault! ;-) > > Alan G > > -------- Forwarded Message -------- > Subject: Re: IDLE: Integrated Development and Learning Environment? > Date: Fri, 2 Oct 2015 17:16:42 -0700 > From: Guido van Rossum > Reply-To: guido at python.org > To: Terry Reedy > CC: idle > Newsgroups: gmane.comp.python.idle > References: <560EF3E2.1060300 at udel.edu> > > <560F0C5F.4030602 at udel.edu> > > > > I think I was reluctant to name it after a living person. I like the > idea of keeping it all caps and changing the interpretation. > > On Fri, Oct 2, 2015 at 3:59 PM, Terry Reedy > wrote: > > On 10/2/2015 6:45 PM, Guido van Rossum wrote: > > I like it. Though of course it's really named after Eric Idle. :-) > > > Until a couple of days ago, I was planning to propose changing > 'IDLE' to 'Idle', which is what I have writen.? I am willing to go > with that change instead.? But I presumed that you must have > preferred the all-caps version, or perhaps not directly naming it > after Eric, and then I thought of how to make 'IDLE' an informative > acronym rather than a clumbsy semi-acronyn.? So now I prefer to > change the interpretation than the spelling. > > -- > Terry Jan Reedy > > > > > -- > --Guido van Rossum (python.org/~guido ) > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From oscar.j.benjamin at gmail.com Tue Oct 6 11:28:58 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Tue, 6 Oct 2015 10:28:58 +0100 Subject: [Tutor] Mutable data type in python In-Reply-To: <56106117.3010403@btinternet.com> References: <560FC9F2.4070102@btinternet.com> <561024BC.10402@btinternet.com> <56106117.3010403@btinternet.com> Message-ID: On 4 October 2015 at 00:13, Alan Gauld wrote: > On 03/10/15 23:20, C Smith wrote: >> >> On Sat, Oct 3, 2015 at 11:55 AM, Alan Gauld >> wrote: >>> >>> On 03/10/15 19:10, C Smith wrote: >>>>> >>>>> Here is my modified version which I think works as you want: >>>>> >>>>> def findMinDepthPath(n): >>>>> if n <= 0: raise ValueError >>>>> elif n==1: >>>>> return 0 >>>>> elif n==2 or n==3: >>>>> return 1 >>>>> else: >>>>> d1 = findMinDepthPath(n-1)+1 >>>>> d2 = d3 = (d1+1) # initialize to higher than d1 >>>>> >>>>> if n%3 == 0: >>>>> d3 = findMinDepthPath(n/3)+1 >>>>> if n%2 == 0: >>>>> d2 = findMinDepthPath(n/2)+1 >>>>> >>>>> return min(d1,d2,d3) >> >> What I meant was that the algorithm assumes that the lowest value from >> one "action" (minus one, divide by 2, divide by 3) is the best >> possible branch in the tree. That seems intuitively correct, but is it >> necessarily so? > > I see. The answer is I don't know mathematically speaking. > But I figured that the minimum path for (n-1|n/2|n/3) plus 1 > must be the minimum path for n. But that was an entirely > inuitive assumption. > > Also because the minimum path is being figured from the > bottom to the top - ie it finds the minimum path for 1..3 > first, then for 4 via n/2 then 5 via n-1 and so on. It *feels* like > that it should always select the minimum path. But I have learnt > that in math intuitive is not always right :-) > > So if anyone can mathematically prove my hunch right > or wrong that would be interesting... Your intuition is fine Alan. Of course it's correct! Starting from a number n there are three possibilities for the first step -1, /2, and /3 each of which counts as one action. Each of those gives a new starting point n1, n2 or n3. Whichever of the ni has the shortest path will also be the shortest path for n except that for n you also need to include the action that gets from n to ni increasing the count by 1. A side point is that the algorithm is incredibly inefficient because the 3 way branching will traverse the same routes many times over. It is analogous to the dumb recursive Fibonacci sequence calculator: def fib(n): if n in (0, 1): return n else: return fib(n-1) + fib(n-2) A typical solution for the inefficiency is to either use a memoisation decorator or to roll it out into an explicit loop instead of a recursive call: def fib(n): n1, n2 = 0, 1 if n in (n1, n2): return n else: for _ in range(1, n): n1, n2 = n2, n1 + n2 return n2 To do the same for this problem you would have something like: def shortest_path(n): paths = [None, 0] for i in range(2, n+1): d1 = paths[i-1] + 1 d2 = paths[i // 2] + 1 if i % 2 == 0 else float('inf') d3 = paths[i // 3] + 1 if i % 3 == 0 else float('inf') paths.append(min(d1, d2, d3)) return paths[n] This way the algorithm is O(n) instead of O(3**n). Also if you actually just want a list of all of the shortest paths you can adjust this to simply return the full list at no extra cost. OTOH if you want to be able to call this function repeatedly with random input values a memoisation decorator may be preferable. -- Oscar From sjeik_appie at hotmail.com Wed Oct 7 18:10:20 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Wed, 7 Oct 2015 16:10:20 +0000 Subject: [Tutor] FrozenDict Message-ID: Hi, I wanted to create a read-only dict to hold some constants. I looked around on the internet and created two implementations:-FrozenDict (derives from collections.mapping)-ChillyDict (derives from dict, which seems more obvious to me) The code can be found here: http://pastebin.com/QJ3V2mSK Some questions:1. one doctest from FrozenDict fails: fd.keys() returns an empty list. Why?2. Is FrozenDict the way to use collections.mapping (aside from the error!). I just discovered this and i seems quite cool (pun intended)3. Which implementation is better, and why? I like ChillyDict better because it is more straightforward and shorter. The read-only dict does not need to be very fast, it just needs to give some reasonable protection against mutating values.It also needs to work under Python 2.7 and 3.3+. Thank you! Albert-Jan From sjeik_appie at hotmail.com Wed Oct 7 21:32:31 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Wed, 7 Oct 2015 19:32:31 +0000 Subject: [Tutor] FrozenDict In-Reply-To: References: Message-ID: > From: sjeik_appie at hotmail.com > To: tutor at python.org > Date: Wed, 7 Oct 2015 16:10:20 +0000 > Subject: [Tutor] FrozenDict > > Hi, > I wanted to create a read-only dict to hold some constants. I looked around on the internet and created two implementations:-FrozenDict (derives from collections.mapping)-ChillyDict (derives from dict, which seems more obvious to me) > The code can be found here: http://pastebin.com/QJ3V2mSK > Some questions:1. one doctest from FrozenDict fails: fd.keys() returns an empty list. Why? ok, the correct way to write __iter__ appears to be: def __iter__(self): return iter(self.__kwargs) Now at least all doctests pass. 2. Is FrozenDict the way to use collections.mapping (aside from the error!). I just discovered this and i seems quite cool (pun intended)3. Which implementation is better, and why? I like ChillyDict better because it is more straightforward and shorter. > The read-only dict does not need to be very fast, it just needs to give some reasonable protection against mutating values.It also needs to work under Python 2.7 and 3.3+. > Thank you! > Albert-Jan Just in case, I am also pasting the code here, with the slightly modified__iter__: from collections import Mapping class FrozenDict(Mapping): """A dictionary that does not support item assignment after initialization >>> fd = FrozenDict(a=1, b=2) >>> fd["a"] 1 >>> fd["a"] = 777 # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... TypeError: 'FrozenDict' object does not support item assignment >>> sorted(fd.items()) [('a', 1), ('b', 2)] >>> sorted(fd.keys()) ['a', 'b'] >>> fd FrozenDict('a'=1, 'b'=2) """ def __init__(self, **kwargs): self.__kwargs = kwargs self.__next__ = self.next self.__counter = 0 self.__init__ = None def __repr__(self): kwargs = ["%r=%r" % (k, v) for k, v in sorted(self.__kwargs.items())] return "%s(%s)" % (self.__class__.__name__, ", ".join(kwargs)) def __getitem__(self, key): return self.__kwargs[key] def __iter__(self): return iter(self.__kwargs) def next(self): try: value = self.__kwargs.items()[self.__counter][0] except IndexError: raise StopIteration self.__counter += 1 return value def __len__(self): return len(self.__kwargs) class ChillyDict(dict): """A dictionary that does not support item assignment after initialization >>> cd = ChillyDict(a=1, b=2) >>> cd["a"] 1 >>> cd["a"] = 777 # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... NotImplementedError: 'ChillyDict' object does not support item assignment >>> sorted(cd.items()) [('a', 1), ('b', 2)] >>> sorted(cd.keys()) ['a', 'b'] >>> cd ChillyDict('a'=1, 'b'=2) """ def __init__(self, **kwargs): self.__kwargs = kwargs super(ChillyDict, self).__init__(**self.__kwargs) self.__init__ = None def __repr__(self): kwargs = ["%r=%r" % (k, v) for k, v in sorted(self.__kwargs.items())] return "%s(%s)" % (self.__class__.__name__, ", ".join(kwargs)) def __not_implemented(self, *args, **kwargs): msg = "'%s' object does not support item assignment" raise NotImplementedError, msg % self.__class__.__name__ __setitem__ = __delitem__ = update = pop = popitem = clear = __not_implemented if __name__ == "__main__": import doctest doctest.testmod() From alex at alexchabot.net Wed Oct 7 18:54:42 2015 From: alex at alexchabot.net (Alexandre Chabot-Leclerc) Date: Wed, 07 Oct 2015 18:54:42 +0200 Subject: [Tutor] FrozenDict In-Reply-To: References: Message-ID: <1444236882.3213768.403991521.4CA691C9@webmail.messagingengine.com> Hi Albert-Jan, As far as I know, the recommended object to subclass when subclassing a `dict` is `UserDict`. In Python 3, it's in `collections.UserDict` and in Python 2 is in `UserDict.UserDict`. Here's an basic example of how it would work: try: from collections import UserDict except ImportError: from UserDict import UserDict class FrozenDict(UserDict): def __setitem__(self, key, item): raise TypeError("'FrozenDict' object does not support item assignment") According to the Fluent Python book (by Luciano Ramalho, which I recommend wholeheartedly), subclassing built-in types is tricky because: "the code of the built-ins (written in C) does not call special methods overridden by user-defined classes." Therefore, other methods of `dict`, like `update` or `__init__` will *not* call your special `__setitem__` method. However, be aware that although the FrozenDict above is read-only, it's not *really* frozen, i.e., it cannot be used as a key in another dict. In order to do that, you would need to define the `__hash__` method. This StackOverflow answer, which you might have seen, provide an implementation of a FrozenDict that could be used as a dict. http://stackoverflow.com/questions/2703599/what-would-a-frozen-dict-be Cheers, Alex On Wed, Oct 7, 2015, at 18:10, Albert-Jan Roskam wrote: > Hi, > I wanted to create a read-only dict to hold some constants. I looked around on the internet and created two implementations:-FrozenDict (derives from collections.mapping)-ChillyDict (derives from dict, which seems more obvious to me) > The code can be found here: http://pastebin.com/QJ3V2mSK > Some questions:1. one doctest from FrozenDict fails: fd.keys() returns an empty list. Why?2. Is FrozenDict the way to use collections.mapping (aside from the error!). I just discovered this and i seems quite cool (pun intended)3. Which implementation is better, and why? I like ChillyDict better because it is more straightforward and shorter. > The read-only dict does not need to be very fast, it just needs to give some reasonable protection against mutating values.It also needs to work under Python 2.7 and 3.3+. > Thank you! > Albert-Jan > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From steve at pearwood.info Thu Oct 8 02:47:41 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 8 Oct 2015 11:47:41 +1100 Subject: [Tutor] FrozenDict In-Reply-To: References: Message-ID: <20151008004741.GF28222@ando.pearwood.info> On Wed, Oct 07, 2015 at 04:10:20PM +0000, Albert-Jan Roskam wrote: > Hi, > I wanted to create a read-only dict to hold some constants. I looked around on the internet and created two implementations:-FrozenDict (derives from collections.mapping)-ChillyDict (derives from dict, which seems more obvious to me) > The code can be found here: http://pastebin.com/QJ3V2mSK > Some questions:1. one doctest from FrozenDict fails: fd.keys() returns > an empty list. Why? No it doesn't. py> fd = FrozenDict(a=1, b=2) py> fd.keys() ['a', 'b'] That's under Python 2.7. In 3.3, you will have a problem that FrozenDict is not a proper iterator. You can't set self.__next__ = self.next, that won't work. Dunder methods have to be on the class, not on the instance, so instead of making the assignment in the __init__ method, put this in the body of your class: def next(self): # Python 2 method ... __next__ = next # Python 3 method. Unfortunately that's not enough to get it working in Python 3. I need more time to think about that. > 2. Is FrozenDict the way to use collections.mapping (aside from the > error!). I just discovered this and i seems quite cool (pun intended) I think the error is quite significant... > 3. Which implementation is better, and why? I like ChillyDict better > because it is more straightforward and shorter. I dislike the ChillyDict implementation because it looks like it supports item assignment: hasattr(ChillyDict, '__setitem__') will return True, but it actually doesn't. That could make it risky in code that assumes that the existence of __setitem__ means you can set items. -- Steve From oscar.j.benjamin at gmail.com Thu Oct 8 13:03:28 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Thu, 8 Oct 2015 12:03:28 +0100 Subject: [Tutor] FrozenDict In-Reply-To: <20151008004741.GF28222@ando.pearwood.info> References: <20151008004741.GF28222@ando.pearwood.info> Message-ID: On 8 October 2015 at 01:47, Steven D'Aprano wrote: > In 3.3, you will have a problem that FrozenDict is not a proper > iterator. You can't set self.__next__ = self.next, that won't work. > Dunder methods have to be on the class, not on the instance, so instead > of making the assignment in the __init__ method, put this in the body of > your class: > > def next(self): > # Python 2 method > ... > > __next__ = next # Python 3 method. > > > Unfortunately that's not enough to get it working in Python 3. I need > more time to think about that. There shouldn't be a __next__ method on the FrozenDict class. __iter__ should return a distinct iterator. Albert has already fixed this by using: def __iter__(self): return iter(self.__kwargs) -- Oscar From andrea.nguy at gmail.com Thu Oct 8 21:40:38 2015 From: andrea.nguy at gmail.com (Andrea Nguy) Date: Thu, 8 Oct 2015 15:40:38 -0400 Subject: [Tutor] Updating index of a list Message-ID: Hi there, I?m trying to learn some Python programming on my own. What?s happening is that I am trying to take a list of a list as such: [['1', ' james', ' 1', ' 90'], ['2', ' alice', ' 1', ' 95'], ['5', ' jorgen', ' 1', ' 99?]] (it continues) from a text file. However, what I am trying to do take the indexes of thelist[0][1] and theist[0][3] and times them by a float number - returning the list with all of the values multiplied according to the float. Is this possible? I am trying to iterate that throughout the entire list or would it be easier if I tried to change the list of the list into a dictionary for efficiency? Thanks! From emile at fenx.com Thu Oct 8 23:29:33 2015 From: emile at fenx.com (Emile van Sebille) Date: Thu, 8 Oct 2015 14:29:33 -0700 Subject: [Tutor] Updating index of a list In-Reply-To: References: Message-ID: On 10/8/2015 12:40 PM, Andrea Nguy wrote: > Hi there, > > I?m trying to learn some Python programming on my own. What?s happening is that I am trying to take a list of a list as such: [['1', ' james', ' 1', ' 90'], ['2', ' alice', ' 1', ' 95'], ['5', ' jorgen', ' 1', ' 99?]] (it continues) from a text file. > > However, what I am trying to do take the indexes of > thelist[0][1] which has a value of 'james' (being index 1 of list 0) > and theist[0][3] which has a value of ' 90' that should get you going. Emile > and times them by a float number - returning the list with all of the values multiplied according to the float. > > Is this possible? I am trying to iterate that throughout the entire list or would it be easier if I tried to change the list of the list into a dictionary for efficiency? > > Thanks! > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at btinternet.com Fri Oct 9 00:17:58 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 8 Oct 2015 23:17:58 +0100 Subject: [Tutor] Updating index of a list In-Reply-To: References: Message-ID: On 08/10/15 20:40, Andrea Nguy wrote: > What?s happening is that I am trying to take a list of a list as such: [['1', ' james', ' 1', ' 90'], ['2', ' alice', ' 1', ' 95'], ['5', ' jorgen', ' 1', ' 99?]] (it continues) from a text file. When you say from a text file, do you mean you are reading the values in and converting them to the appropriate types? Or are you just adding them directly to the list? In which case they will all be strings? > However, what I am trying to do take the indexes of thelist[0][1] > and thelist[0][3] and times them by a float number > - returning the list with all of the values multiplied according to the float. > Is this possible? Yes of course. just use a for loop like this: for sublist in thelist: sublist[0] *= someFloat sublist[3] *= someFloat Which changes the values in place. Or a little more advanced you can use a list comprehension: newlist = [[sub[0]*someFloat, sub[1],[sub[2],sub[3]*someFloat] for sub in thelist] Which will create a new list with the values you desire leaving the original list unchanged. > would it be easier if I tried to change the list of the > list into a dictionary for efficiency? While changing data type is often the right thing to do to make the code clearer, thinking about efficiency before you know you have a problem is nearly always the wrong thing 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 steve at pearwood.info Fri Oct 9 00:37:00 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 9 Oct 2015 09:37:00 +1100 Subject: [Tutor] Updating index of a list In-Reply-To: References: Message-ID: <20151008223700.GG28222@ando.pearwood.info> Hi Andrea, and welcome. My responses inline, below. On Thu, Oct 08, 2015 at 03:40:38PM -0400, Andrea Nguy wrote: > Hi there, > > I?m trying to learn some Python programming on my own. What?s > happening is that I am trying to take a list of a list as such: [['1', > ' james', ' 1', ' 90'], ['2', ' alice', ' 1', ' 95'], ['5', ' jorgen', > ' 1', ' 99?]] (it continues) from a text file. Okay, I assume you know how to read the data from the text file and build the list of lists. If not, let us know. I'll also assume that the leading spaces in some of the items are deliberate. What version of Python are you using? That may make a difference to the answers. So let's just say we have: thelist = [['1', ' james', ' 1', ' 90'], ['2', ' alice', ' 1', ' 95'], ['5', ' jorgen', ' 1', ' 99?], ] > However, what I am trying to do take the indexes of thelist[0][1] and > theist[0][3] and times them by a float number - returning the list > with all of the values multiplied according to the float. I'm not really sure I understand what you are trying to do here. If I take you literally, you want something like this: - take thelist[0][1] # returns ' james' - extract the indexes of that string # returns [0, 1, 2, 3, 4, 5] - take thelist[0][3] # returns ' 90' - extract the indexes of that string # returns [0, 1, 2] - concatenate with the first list # returns [0, 1, 2, 3, 4, 5, 0, 1, 2] - multiply by some mystery float (say, 1.5) # returns [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 0.0, 1.5, 3.0] This is certainly possible, but I'm not sure that it is what you want. Can you confirm that it is, or explain a little better what you want? If possible, show your expected output. But, for the record, here is one way to do the above: results = [] for i in (1, 3): word = thelist[0][i] results.extend(range(len(word))) for i, n in enumerate(results): results[i] = n*1.5 print(results) You may or may not understand all that code. If you don't, please say so and we'll explain. > Is this possible? I am trying to iterate that throughout the entire > list or would it be easier if I tried to change the list of the list > into a dictionary for efficiency? If you converted the list-of-lists into a dictionary, what would it look like? P.S. please keep your replies on the list, so that others may help, or learn from your questions. -- Steve From alan.gauld at btinternet.com Fri Oct 9 02:38:29 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 9 Oct 2015 01:38:29 +0100 Subject: [Tutor] Updating index of a list In-Reply-To: References: Message-ID: On 08/10/15 23:17, Alan Gauld wrote: > On 08/10/15 20:40, Andrea Nguy wrote: > >> What?s happening is that I am trying to take a list of a list as such: > > [['1', ' james', ' 1', ' 90'], > ['2', ' alice', ' 1', ' 95'], > ['5', ' jorgen', ' 1', ' 99?]] (it continues) from a text file. > > When you say from a text file, do you mean you are reading the > values in and converting them to the appropriate types? Or are > you just adding them directly to the list? In which case they > will all be strings? Its late so I'm not reading clearly enough. They are all strings. So I suspect before multiplying by a float your first job is to convert the numbers to floats(or ints) using float() (or int()) >> However, what I am trying to do take the indexes of thelist[0][1] And I didn't notice this was [0,1] (' james') but read it as [1,0] (2) > just use a for loop like this: > > for sublist in thelist: > sublist[0] *= someFloat > sublist[3] *= someFloat > > Which changes the values in place. Provided its the numbers you want and you convert them to float/int first. Sorry for my inattention, -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Fri Oct 9 03:18:46 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 9 Oct 2015 12:18:46 +1100 Subject: [Tutor] FrozenDict In-Reply-To: References: <20151008004741.GF28222@ando.pearwood.info> Message-ID: <20151009011846.GH28222@ando.pearwood.info> On Thu, Oct 08, 2015 at 12:03:28PM +0100, Oscar Benjamin wrote: > On 8 October 2015 at 01:47, Steven D'Aprano wrote: > > In 3.3, you will have a problem that FrozenDict is not a proper > > iterator. You can't set self.__next__ = self.next, that won't work. > > Dunder methods have to be on the class, not on the instance, so instead > > of making the assignment in the __init__ method, put this in the body of > > your class: > > > > def next(self): > > # Python 2 method > > ... > > > > __next__ = next # Python 3 method. > > > > > > Unfortunately that's not enough to get it working in Python 3. I need > > more time to think about that. > > There shouldn't be a __next__ method on the FrozenDict class. __iter__ > should return a distinct iterator. Albert has already fixed this by > using: > > def __iter__(self): > return iter(self.__kwargs) That's one solution, but it is certainly possible for the class to be its own iterator, in which case it needs to follow two rules: (1) self.__next__() needs to return the next value, or raise StopIteration; (2) self.__iter__() needs to return self; and of course like all dunder methods __next__ and __iter__ need to be defined on the class itself, not on the instance. Just returning iter(values) is probably much easier, but not as much fun :-) -- Steve From eryksun at gmail.com Fri Oct 9 08:14:05 2015 From: eryksun at gmail.com (eryksun) Date: Fri, 9 Oct 2015 01:14:05 -0500 Subject: [Tutor] FrozenDict In-Reply-To: <20151009011846.GH28222@ando.pearwood.info> References: <20151008004741.GF28222@ando.pearwood.info> <20151009011846.GH28222@ando.pearwood.info> Message-ID: On 10/8/15, Steven D'Aprano wrote: > > That's one solution, but it is certainly possible for the class to be > its own iterator, in which case it needs to follow two rules: > > (1) self.__next__() needs to return the next value, or raise > StopIteration; > > (2) self.__iter__() needs to return self; > > and of course like all dunder methods __next__ and __iter__ need to be > defined on the class itself, not on the instance. Except this is generally a bad way to iterate a reiterable. Without a separate iterator, there's no simple way to maintain state for concurrent iterations. file types are an exception. A file is reiterable (i.e. by seeking back to 0), but the OS file pointer makes a file naturally an iterator. Thus getting concurrent iterations of a disk file requires separate file objects that have separate OS file pointers. FrozenDict.next is an example of what not to do: def next(self): try: value = self.__kwargs.items()[self.__counter][0] except IndexError: raise StopIteration self.__counter += 1 return value In Python 2 this iterates the dict's keys by creating a list of (key, value) tuples -- every time next() is called. In Python 3, you'd have to explicitly create the list using list(self.__kwargs.items()). The design also lacks support for concurrent iterations, and not even multiple iterations since __counter isn't reset in __iter__. The simple approach is to have __iter__ return an instance of the wrapped dict's iterator. There's no reason to reinvent the wheel. Plus in the non-frozen case, the built-in dict iterators are smart enough to raise an error when the dict is modified, since it's assumed that any modification to the hash table invalidates the iteration. From anshu.kumar726 at gmail.com Fri Oct 9 03:59:44 2015 From: anshu.kumar726 at gmail.com (Anshu Kumar) Date: Fri, 9 Oct 2015 07:29:44 +0530 Subject: [Tutor] Updating index of a list In-Reply-To: References: Message-ID: Hi Andrea, You can use lambda or list comprehension to solve your problem in one step. I am more comfortable with lambda so will explain that way. Please follow below lines of code. andreea_list = [['1', ' james', ' 1', ' 90'], ['2', ' alice', ' 1', ' 95'], ['5', ' jorgen', ' 1', '99']] andrea_float_list = map(lambda x:float(x[0]),andreea_list) print andrea_float_list map is function which takes two arguments first is an anonymous function called lamda which operates on each of the list element one at a time and the other is list it self. you can read about lambdas here http://www.python-course.eu/lambda.php Thanks , Anshu On Fri, Oct 9, 2015 at 1:10 AM, Andrea Nguy wrote: > Hi there, > > I?m trying to learn some Python programming on my own. What?s happening is > that I am trying to take a list of a list as such: [['1', ' james', ' 1', ' > 90'], ['2', ' alice', ' 1', ' 95'], ['5', ' jorgen', ' 1', ' 99?]] (it > continues) from a text file. > > However, what I am trying to do take the indexes of thelist[0][1] and > theist[0][3] and times them by a float number - returning the list with all > of the values multiplied according to the float. > > Is this possible? I am trying to iterate that throughout the entire list > or would it be easier if I tried to change the list of the list into a > dictionary for efficiency? > > Thanks! > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From nickbrodsky1999 at gmail.com Fri Oct 9 05:31:17 2015 From: nickbrodsky1999 at gmail.com (Nick Brodsky) Date: Thu, 8 Oct 2015 23:31:17 -0400 Subject: [Tutor] Help with else Message-ID: name = raw_input("What is your name") print "Great! Now %s, are you a boy or a girl?" % (name) gender = raw_input("") if gender == "boy": print " I can see that, you are very strong": if gender == "girl": print ' Yes, and a beautiful one': else: print "Your choice" I don't understand why it doesn't work, it just skips over the else. Thanks for the help! Montreallisting.ca Free Montreal Classifieds Gaminggame.com Best Game Reviews You'll Find From sasuke510ca at gmail.com Fri Oct 9 02:13:44 2015 From: sasuke510ca at gmail.com (Sasuke Uchiha) Date: Thu, 8 Oct 2015 17:13:44 -0700 Subject: [Tutor] Python 3.5 Question Message-ID: Hi, I would like to know how to create a code similar to the result below. I want to input a number like 1000, and for it to give me the maximum output with the least amount of bills (such as 100s) - The bill amounts you have are 100s, 50s, 20s, 10s, 5s, and 1s - >>> Please enter the amount of money you wish to withdraw: 1737 You received: 17 hundreds. 0 fifties. 1 twenties. 1 tens. 1 fives. 2 ones. >>> Please enter the amount of money you wish to withdraw: 168 You received: 1 hundreds. 1 fifties. 0 twenties. 1 tens. 1 fives. 3 ones. From alan.gauld at btinternet.com Fri Oct 9 11:21:17 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 9 Oct 2015 10:21:17 +0100 Subject: [Tutor] Help with else In-Reply-To: References: Message-ID: On 09/10/15 04:31, Nick Brodsky wrote: > name = raw_input("What is your name") > > print "Great! Now %s, are you a boy or a girl?" % (name) > > gender = raw_input("") > > if gender == "boy": > print " I can see that, you are very strong": > if gender == "girl": > print ' Yes, and a beautiful one': > else: > print "Your choice" > > > I don't understand why it doesn't work, it just skips over the else. Not for me it didn't, it gave an error. Please always post exactly what the program produces don't try to summarize. In this case there are several potential errors but the first thing to fix are the colons after the print statements. You only need colons on the end of control statements such as for, while, if/else etc. The second thing that I see is that although (I assume) you only want the 'your choice' to print if the user selects something other than boy/girl it will print even for boy. That's because the boy section is in a separate if statement. Like this simplified snippet: if boy: print.... if girl: print... else: print... But I think you wanted if boy: print... elif girl: print ... else: print... Can you see the difference in logic? HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From ben+python at benfinney.id.au Fri Oct 9 11:23:05 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 09 Oct 2015 20:23:05 +1100 Subject: [Tutor] Python 3.5 Question References: Message-ID: <85zizswg3q.fsf@benfinney.id.au> Sasuke Uchiha writes: > Hi, I would like to know how to create a code similar to the result > below. Is this an assignment for you? We aren't a service to do homework. Can you show some code you have written to try solving the problem? We can discuss what you have already tried. You may also be interested in the Python Tutor forum which is specially focussed on collaboratively teaching Python beginners. -- \ ?When I was born I was so surprised I couldn't talk for a year | `\ and a half.? ?Gracie Allen | _o__) | Ben Finney From alan.gauld at btinternet.com Fri Oct 9 11:26:52 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 9 Oct 2015 10:26:52 +0100 Subject: [Tutor] Python 3.5 Question In-Reply-To: References: Message-ID: On 09/10/15 01:13, Sasuke Uchiha wrote: > Hi, I would like to know how to create a code similar to the result below. > I want to input a number like 1000, and for it to give me the maximum > output with the least amount of bills (such as 100s) > This looks like homework and we won't do your homework for you. But we can offer hints. It will help if you show us any code you have written or even tell us how you think it might work. Meantime, look into the integer division and modulo operators. They can be combined via the divmod() function which returns both the division result and remainder in a single operation like this: hundreds,dollars = divmod(1737,100) and hundreds will equal 17 and dollars 37. hopefully you can see how that can be applied to your problem. If not come back and ask more. > >>> > Please enter the amount of money you wish to withdraw: 1737 You received: > 17 hundreds. > 0 fifties. > 1 twenties. > 1 tens. > 1 fives. > 2 ones. -- 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 Fri Oct 9 11:36:36 2015 From: __peter__ at web.de (Peter Otten) Date: Fri, 09 Oct 2015 11:36:36 +0200 Subject: [Tutor] How to write a teller machine simulation, was Re: Python 3.5 Question References: Message-ID: Sasuke Uchiha wrote: > Hi, I would like to know how to create a code similar to the result below. > I want to input a number like 1000, and for it to give me the maximum > output with the least amount of bills (such as 100s) > > - > > The bill amounts you have are 100s, 50s, 20s, 10s, 5s, and 1s > - > > >>> > Please enter the amount of money you wish to withdraw: 1737 You > received: 17 hundreds. > 0 fifties. > 1 twenties. > 1 tens. > 1 fives. > 2 ones. We don't do your homework, but as this is a common task for students there is a site that does enough handholding to get you started: http://cs.smith.edu/dftwiki/index.php/CSC111_Lab_2_2014 If you run into problems and have a little code to show you made an effort yourself we will help you solve them. From ben+python at benfinney.id.au Fri Oct 9 17:47:37 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Sat, 10 Oct 2015 02:47:37 +1100 Subject: [Tutor] Python 3.5 Question References: <85zizswg3q.fsf@benfinney.id.au> Message-ID: <85r3l4vyau.fsf@benfinney.id.au> Ben Finney writes: > You may also be interested in the Python Tutor forum > which is specially > focussed on collaboratively teaching Python beginners. Whoops, my apology! I failed to notice we are already in that forum :-) -- \ ?He may look like an idiot and talk like an idiot but don't let | `\ that fool you. He really is an idiot.? ?Groucho Marx | _o__) | Ben Finney From aenesunal at gmail.com Fri Oct 9 11:07:19 2015 From: aenesunal at gmail.com (Enes Unal) Date: Fri, 9 Oct 2015 12:07:19 +0300 Subject: [Tutor] Help with else In-Reply-To: References: Message-ID: may be this one? name = raw_input("What is your name") print "Great! Now %s, are you a boy or a girl?" % (name) gender = raw_input("") if gender == "boy": print " I can see that, you are very strong" elif gender == "girl": print ' Yes, and a beautiful one' else: print "Your choice" > On 09 Oct 2015, at 06:31, Nick Brodsky wrote: > > name = raw_input("What is your name") > > print "Great! Now %s, are you a boy or a girl?" % (name) > > gender = raw_input("") > > if gender == "boy": > print " I can see that, you are very strong": > if gender == "girl": > print ' Yes, and a beautiful one': > else: > print "Your choice" > > > I don't understand why it doesn't work, it just skips over the else. Thanks for > > the help! > > > Montreallisting.ca > Free Montreal Classifieds > > > Gaminggame.com > Best Game Reviews You'll Find > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From David.Aldrich at EMEA.NEC.COM Fri Oct 9 17:02:20 2015 From: David.Aldrich at EMEA.NEC.COM (David Aldrich) Date: Fri, 9 Oct 2015 15:02:20 +0000 Subject: [Tutor] How to read all integers from a binary file? Message-ID: <41302A7145AC054FA7A96CFD03835A0A0B9EAC21@EX10MBX02.EU.NEC.COM> Hi I have a binary file of 32-bit unsigned integers. I want to read all those integers into a list. I have: ulData = [] with open(ulBinFileName, "rb") as inf: ulData.append(struct.unpack('i', inf.read(4))) This obviously reads only one integer from the file. How would I modify this code to read all integers from the file please? Best regards David From __peter__ at web.de Fri Oct 9 20:49:40 2015 From: __peter__ at web.de (Peter Otten) Date: Fri, 09 Oct 2015 20:49:40 +0200 Subject: [Tutor] How to read all integers from a binary file? References: <41302A7145AC054FA7A96CFD03835A0A0B9EAC21@EX10MBX02.EU.NEC.COM> Message-ID: David Aldrich wrote: > Hi > > I have a binary file of 32-bit unsigned integers. I want to read all those > integers into a list. > > I have: > > ulData = [] > with open(ulBinFileName, "rb") as inf: > ulData.append(struct.unpack('i', inf.read(4))) > > This obviously reads only one integer from the file. How would I modify > this code to read all integers from the file please? While the obvious approach would be a loop data = [] # no misleading prefixes, please while True: four_bytes = inf.read(4) if len(four_bytes) != 4: if four_bytes: raise ValueError("number of bytes not a multiple of 4") break data.append(struct.unpack("i", four_bytes)) there is also the array module: data = array.array("i", inf.read()) You can convert the array to a list with data = data.tolist() if necessary. From lac at openend.se Fri Oct 9 20:57:15 2015 From: lac at openend.se (Laura Creighton) Date: Fri, 09 Oct 2015 20:57:15 +0200 Subject: [Tutor] How to read all integers from a binary file? In-Reply-To: <41302A7145AC054FA7A96CFD03835A0A0B9EAC21@EX10MBX02.EU.NEC.COM> References: <41302A7145AC054FA7A96CFD03835A0A0B9EAC21@EX10MBX02.EU.NEC.COM> Message-ID: <201510091857.t99IvFrN030782@fido.openend.se> In a message of Fri, 09 Oct 2015 15:02:20 -0000, David Aldrich writes: >Hi > >I have a binary file of 32-bit unsigned integers. I want to read all those integers into a list. > >I have: > > ulData = [] > with open(ulBinFileName, "rb") as inf: > ulData.append(struct.unpack('i', inf.read(4))) > >This obviously reads only one integer from the file. How would I modify this code to read all integers from the file please? > >Best regards > >David You did the hard part, finding the struct module: and I assume that you got struct_unpack defined somewhere You need to wrap that up in: with open(ulBinFileName, "rb") as inf: while True: data = inf.read(4) if not data: break ulData.append(struct.unpack('i', data)) Laura From martin at linux-ip.net Fri Oct 9 21:26:09 2015 From: martin at linux-ip.net (Martin A. Brown) Date: Fri, 9 Oct 2015 12:26:09 -0700 Subject: [Tutor] How to read all integers from a binary file? In-Reply-To: <41302A7145AC054FA7A96CFD03835A0A0B9EAC21@EX10MBX02.EU.NEC.COM> References: <41302A7145AC054FA7A96CFD03835A0A0B9EAC21@EX10MBX02.EU.NEC.COM> Message-ID: Hello there David, > I have a binary file of 32-bit unsigned integers. I want to read > all those integers into a list. > > I have: > > ulData = [] > with open(ulBinFileName, "rb") as inf: > ulData.append(struct.unpack('i', inf.read(4))) > > This obviously reads only one integer from the file. How would I > modify this code to read all integers from the file please? I see you already have responses from Laura Creighton and Peter Otten. I particularly like the idea of using array.array() to read the data. You can also use a number in the format string to indicate how many times you want to apply the format string. For example, assume your data file was exactly 20 bytes long and has been read into memory as a variable called binary_data. Now you want to make a list containing 5 of these unsigned integers. Well, you can do this: l = struct.unpack('5i', binary_data) # -- that would give you this tuple (fabricated data) # # l = (-1682686882, 2011801612, -366700247, 463482871, 1463075426) Below, you can see what I did to generalize this technique in the function read_data(). If, however, you do not have complex data, then array.array() is probably the easiest path for you. Good luck and have fun! -Martin from __future__ import print_function import sys import struct def write_data(f, size, datatype): data = gen_data(size) fmt = str(len(data)) + datatype s = struct.pack(fmt, *data) f.write(s) f.close() def gen_data(size): import numpy data = list(numpy.random.randint(-(2**31)+1, 2**31, size=size)) return data def read_data(f, datatype): s = f.read() f.close() element_size = struct.calcsize(datatype) q, r = divmod(len(s), element_size) assert r == 0 fmt = str(int(len(s) / element_size)) + 'i' data = struct.unpack(fmt, s) return data if __name__ == '__main__': if len(sys.argv) > 2: size = int(sys.argv[2]) write_data(open(sys.argv[1], 'wb'), size, 'i') data = read_data(open(sys.argv[1], 'rb'), 'i') print(len(data)) P.S. You'll see that I didn't have a mess of unsigned integers hanging around in a file, so you can see how I generated and stored them in write_data and gen_data). -- Martin A. Brown http://linux-ip.net/ From breamoreboy at yahoo.co.uk Sat Oct 10 01:22:40 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 10 Oct 2015 00:22:40 +0100 Subject: [Tutor] Python 3.5 Question In-Reply-To: <85r3l4vyau.fsf@benfinney.id.au> References: <85zizswg3q.fsf@benfinney.id.au> <85r3l4vyau.fsf@benfinney.id.au> Message-ID: On 09/10/2015 16:47, Ben Finney wrote: > Ben Finney writes: > >> You may also be interested in the Python Tutor forum >> which is specially >> focussed on collaboratively teaching Python beginners. > > Whoops, my apology! I failed to notice we are already in that forum :-) > I simply had to roar with laughter at the signature you used for the above as it just seemed so apt, nothing personal :) \ ?He may look like an idiot and talk like an idiot but don't let | `\ that fool you. He really is an idiot.? ?Groucho Marx | _o__) | Ben Finney -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From ben+python at benfinney.id.au Sat Oct 10 03:10:29 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Sat, 10 Oct 2015 12:10:29 +1100 Subject: [Tutor] Python 3.5 Question References: <85zizswg3q.fsf@benfinney.id.au> <85r3l4vyau.fsf@benfinney.id.au> Message-ID: <85mvvrwmt6.fsf@benfinney.id.au> Mark Lawrence writes: > On 09/10/2015 16:47, Ben Finney wrote: > > Whoops, my apology! I failed to notice we are already in that forum > > :-) > > I simply had to roar with laughter at the signature you used for the > above as it just seemed so apt, nothing personal :) > > > \ ?He may look like an idiot and talk like an idiot but don't let | > `\ that fool you. He really is an idiot.? ?Groucho Marx | > _o__) | > Ben Finney > Yes. Good sigmonster, have a cookie! I don't pick the aphorisms, but I do get to see them before sending the message. I found it totally apt also :-) -- \ Fry: ?Take that, poor people!? Leela: ?But Fry, you?re not | `\ rich.? Fry: ?No, but I will be someday, and then people like | _o__) me better watch out!? ?Futurama | Ben Finney From sjeik_appie at hotmail.com Sat Oct 10 13:28:05 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Sat, 10 Oct 2015 11:28:05 +0000 Subject: [Tutor] FrozenDict In-Reply-To: <1444236882.3213768.403991521.4CA691C9@webmail.messagingengine.com> References: , <1444236882.3213768.403991521.4CA691C9@webmail.messagingengine.com> Message-ID: ---------------------------------------- > From: alex at alexchabot.net > To: tutor at python.org > Date: Wed, 7 Oct 2015 18:54:42 +0200 > Subject: Re: [Tutor] FrozenDict > > Hi Albert-Jan, > As far as I know, the recommended object to subclass when subclassing a `dict` is `UserDict`. In Python 3, it's in `collections.UserDict` and in Python 2 is in `UserDict.UserDict`. > > Here's an basic example of how it would work: > > try: > from collections import UserDict > except ImportError: > from UserDict import UserDict > > class FrozenDict(UserDict): > def __setitem__(self, key, item): > raise TypeError("'FrozenDict' object does not support item assignment") > > According to the Fluent Python book (by Luciano Ramalho, which I recommend wholeheartedly), subclassing built-in types is tricky because: "the code of the built-ins (written in C) does not call special methods overridden by user-defined classes." Therefore, other methods of `dict`, like `update` or `__init__` will *not* call your special `__setitem__` method. > > However, be aware that although the FrozenDict above is read-only, it's not *really* frozen, i.e., it cannot be used as a key in another dict. In order to do that, you would need to define the `__hash__` method. > > This StackOverflow answer, which you might have seen, provide an implementation of a FrozenDict that could be used as a dict. > http://stackoverflow.com/questions/2703599/what-would-a-frozen-dict-be > > Cheers, > Alex > Aha, that's useful to know. So it's a no-no to subclass *any* builtin? I checked collections.UserDict and it indeed looks promising. Caveat: it;s Python 3 only (not sure what versionit was introduced). Best wishes, Albert-Jan From sjeik_appie at hotmail.com Sat Oct 10 13:31:23 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Sat, 10 Oct 2015 11:31:23 +0000 Subject: [Tutor] FrozenDict In-Reply-To: <20151008004741.GF28222@ando.pearwood.info> References: , <20151008004741.GF28222@ando.pearwood.info> Message-ID: ---------------------------------------- > Date: Thu, 8 Oct 2015 11:47:41 +1100 > From: steve at pearwood.info > To: tutor at python.org > Subject: Re: [Tutor] FrozenDict > > On Wed, Oct 07, 2015 at 04:10:20PM +0000, Albert-Jan Roskam wrote: >> Hi, >> I wanted to create a read-only dict to hold some constants. I looked around on the internet and created two implementations:-FrozenDict (derives from collections.mapping)-ChillyDict (derives from dict, which seems more obvious to me) >> The code can be found here: http://pastebin.com/QJ3V2mSK > >> Some questions:1. one doctest from FrozenDict fails: fd.keys() returns >> an empty list. Why? > > No it doesn't. > > py> fd = FrozenDict(a=1, b=2) > py> fd.keys() > ['a', 'b'] > > > That's under Python 2.7. > > In 3.3, you will have a problem that FrozenDict is not a proper > iterator. You can't set self.__next__ = self.next, that won't work. > Dunder methods have to be on the class, not on the instance, so instead > of making the assignment in the __init__ method, put this in the body of > your class: > > def next(self): > # Python 2 method > ... > > __next__ = next # Python 3 method. > > > Unfortunately that's not enough to get it working in Python 3. I need > more time to think about that. > > >> 2. Is FrozenDict the way to use collections.mapping (aside from the >> error!). I just discovered this and i seems quite cool (pun intended) > > I think the error is quite significant... > > >> 3. Which implementation is better, and why? I like ChillyDict better >> because it is more straightforward and shorter. > > I dislike the ChillyDict implementation because it looks like it > supports item assignment: > > hasattr(ChillyDict, '__setitem__') Thanks. I had not considered that. I usually use try-except (forgiveness) rather than hasattr (permission) I will post another implementation shortly. > > will return True, but it actually doesn't. That could make it risky in > code that assumes that the existence of __setitem__ means you can set > items. > > > > -- > Steve > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From sjeik_appie at hotmail.com Sat Oct 10 13:39:53 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Sat, 10 Oct 2015 11:39:53 +0000 Subject: [Tutor] FrozenDict In-Reply-To: References: , <20151008004741.GF28222@ando.pearwood.info>, , <20151009011846.GH28222@ando.pearwood.info>, Message-ID: ---------------------------------------- > Date: Fri, 9 Oct 2015 01:14:05 -0500 > From: eryksun at gmail.com > To: tutor at python.org > Subject: Re: [Tutor] FrozenDict > > On 10/8/15, Steven D'Aprano wrote: >> >> That's one solution, but it is certainly possible for the class to be >> its own iterator, in which case it needs to follow two rules: >> >> (1) self.__next__() needs to return the next value, or raise >> StopIteration; >> >> (2) self.__iter__() needs to return self; >> >> and of course like all dunder methods __next__ and __iter__ need to be >> defined on the class itself, not on the instance. > > Except this is generally a bad way to iterate a reiterable. Without a > separate iterator, there's no simple way to maintain state for > concurrent iterations. > > file types are an exception. A file is reiterable (i.e. by seeking > back to 0), but the OS file pointer makes a file naturally an > iterator. Thus getting concurrent iterations of a disk file requires > separate file objects that have separate OS file pointers. > > FrozenDict.next is an example of what not to do: > > def next(self): > try: > value = self.__kwargs.items()[self.__counter][0] > except IndexError: > raise StopIteration > self.__counter += 1 > return value > > In Python 2 this iterates the dict's keys by creating a list of (key, > value) tuples -- every time next() is called. In Python 3, you'd have > to explicitly create the list using list(self.__kwargs.items()). The > design also lacks support for concurrent iterations, and not even > multiple iterations since __counter isn't reset in __iter__. Hi Erysun, Steven and others. Eww, I see now that this indeed horribly inefficient. > > The simple approach is to have __iter__ return an instance of the > wrapped dict's iterator. There's no reason to reinvent the wheel. Plus > in the non-frozen case, the built-in dict iterators are smart enough > to raise an error when the dict is modified, since it's assumed that > any modification to the hash table invalidates the iteration. I don't understand what you mean with this. It reads like super(FrozenDict, self).__iter__(), but that can't be correct because the supper class is an abstract class. Anyway, I rewrote the code (__repr__ is omitted for brevity): from collections import Mapping import sys class FrozenDict(Mapping): ??? """A dictionary that does not support item assignment after initialization ???>>> fd = FrozenDict(a=1, b=2) ???>>> fd["a"] ??? 1 ???>>> fd["a"] = 777? # doctest: +IGNORE_EXCEPTION_DETAIL ??? Traceback (most recent call last): ??? ... ??? TypeError: 'FrozenDict' object does not support item assignment ???>>> sorted(fd.items()) ??? [('a', 1), ('b', 2)] ???>>> sorted(fd.keys()) ??? ['a', 'b'] ??? """ ??? def __init__(self, **kwargs): ??????? self.__kwargs = kwargs ??????? self.__init__ = None ??? def __getitem__(self, key): ??????? return self.__kwargs[key] ??? def __iter__(self): ??????? return self.__kwargs.iterkeys() ??? if sys.version_info.major> 2: ??????? __iter__ = lambda self: iter(self.__kwargs.keys()) ? # Python 3: I am assuming this approach is more efficient than using try-except. ??? def __len__(self): ??????? return len(self.__kwargs) Curious what you think about this code. By the way, why is a TyperError raised when one tries to set an item? An AttributeError seems more logical. if __name__ == "__main__": ??? import doctest ??? doctest.testmod() As always, thanks a lot! Best wishes, Albert-Jan ? From alex at alexchabot.net Sat Oct 10 15:30:18 2015 From: alex at alexchabot.net (Alexandre Chabot-Leclerc) Date: Sat, 10 Oct 2015 15:30:18 +0200 Subject: [Tutor] FrozenDict In-Reply-To: References: <1444236882.3213768.403991521.4CA691C9@webmail.messagingengine.com> Message-ID: <1444483818.2251549.406584425.1E31AD45@webmail.messagingengine.com> > Aha, that's useful to know. So it's a no-no to subclass *any* builtin? I don't think it's a no-no, I just think it comes with a few problems that are solved if you subclass the classes that are *meant* to be subclassed, like UserDict, UserList, or UserString. > I checked collections.UserDict and it indeed looks promising. Caveat: it;s Python 3 only (not sure what versionit was introduced). It's in both Python 2 and 3, but they're not in the same module. That's why I used the following construct to import it. In both cases, UserDict is imported correctly and the module where it came from does not matter. try: from collections import UserDict except ImportError: from UserDict import UserDict Here are the docs: - Python 2: https://docs.python.org/2/library/userdict.html - Python 3: https://docs.python.org/3/library/collections.html#collections.UserDict Regards, Alex From akleider at sonic.net Sun Oct 11 02:41:17 2015 From: akleider at sonic.net (Alex Kleider) Date: Sat, 10 Oct 2015 17:41:17 -0700 Subject: [Tutor] how to unittest cli input Message-ID: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> """ I'm trying to follow a test driven development paradigm (using unittest) but can't figure out how to test functions that collect info from the command line such as the following. """ # collect.py def collect_data(): ret = {} ret['first'] = input("Enter your first name: ") ret['last'] = input("Enter your last name: ") ret['phone'] = input("Your mobile phone #: ") return ret def main(): print(collect_data()) if __name__ == "__main__": main() The following works: $ python3 collect.py < cli_input # cli_input Alex Kleider 415/868-1920 ... but I don't know how to make it a unittest. Thanks in advance for any suggestions. Alex From ben+python at benfinney.id.au Sun Oct 11 03:14:52 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Sun, 11 Oct 2015 12:14:52 +1100 Subject: [Tutor] how to unittest cli input References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> Message-ID: <85si5iurxv.fsf@benfinney.id.au> Alex Kleider writes: > """ > I'm trying to follow a test driven development paradigm (using > unittest) but can't figure out how to test functions that collect > info from the command line such as the following. > """ > # collect.py > def collect_data(): > ret = {} > ret['first'] = input("Enter your first name: ") > ret['last'] = input("Enter your last name: ") > ret['phone'] = input("Your mobile phone #: ") > return ret To collect information from the command line, a program interrogates ?sys.argv?. The example you show, rather, gets *interactive* input from the user. That's not command-line, so it's important to get the terminology right. You can write unit tests for this kind of function by making a ?test double? for the ?input? function: an instrumented replacement (a ?double?) that behaves exactly as you determine in the test case. One common way is to make a collection of data scenarios, and write test cases that use each scenario to set up the environment, call the function, and make one assertion about the result. import builtins import unittest import unittest.mock import testscenarios from .. import collect class collect_data_TestCase( testscenarios.WithScenarios, unittest.TestCase): """ Test cases for the `collect_data` function. """ scenarios = [ ('simple', { 'input_lines': [ "Lorem", "Ipsum", "+61 412 345 678", ], 'expected_result': { 'first': "Lorem", 'last': "Ipsum", 'phone': "+61 412 345 678", }, }), ('empty', { 'input_lines': [""] * 3, 'expected_result': { 'first': "", 'last': "", 'phone': ""}, }), ] def setUp(self): """ Set up test fixtures for the test case. """ # Perform setup from all superclasses. This ensures each # test case will get attributes assigned from the scenario. super().setUp() # Makes a ?patcher? to patch the ?builtins.input? # function, replacing it with an instrumented test double # (a MagicMock) that will return the next ?input_lines? # value each time it is called. func_patcher = unittest.mock.patch.object( builtins, "input", side_effect=self.input_lines) # Start the patcher (i.e. replace the real function) for # this test case. func_patcher.start() # Register the patcher's ?stop? (i.e. restore the original # function) as a clean-up action for this test case. self.addCleanup(func_patcher.stop) def test_returns_expected_result(self): """ Should return the result expected for the intputs. """ result = collect.collect_data() self.assertEqual(self.expected_result, result) The ?testscenarios? third-party library is recommended for data-driven tests . It will, at run-time, create a separate test case for each test case function ? each scenario defined for that function's class. All the produced test cases will run separately, identified by the test case method and the scenario name; and each one will fail or pass separately. This makes it very easy to test a matrix of assertions versus input/output expectations. The ?unittest.mock? library is part of the Python 3 standard library, and is good for creating powerful test doubles . -- \ ?Airports are ugly. Some are very ugly. Some attain a degree of | `\ ugliness that can only be the result of a special effort.? | _o__) ?Douglas Adams, _The Long Dark Tea-Time of the Soul_, 1988 | Ben Finney From cs at zip.com.au Sun Oct 11 03:10:54 2015 From: cs at zip.com.au (Cameron Simpson) Date: Sun, 11 Oct 2015 12:10:54 +1100 Subject: [Tutor] how to unittest cli input In-Reply-To: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> Message-ID: <20151011011054.GA40283@cskk.homeip.net> On 10Oct2015 17:41, Alex Kleider wrote: >I'm trying to follow a test driven development paradigm (using >unittest) but can't figure out how to test functions that collect >info from the command line such as the following. Aside: I'd say "the standard input" , not "the command line"; to me the latter connotes to command line arguments fro sys.argv. Anyway, ... I would supply test data either as a string in the unit tests or as a file kept with the source tree eg: os.path.join(os.path.dirname(__file__), 'test_data.txt') and then parameterise the input source in you functions. For example: def collect_data(src=None): if src is None: src = sys.stdin and supply src. However, you'r eusing input(), which unconditionally uses stdin and stdout. In that circumstance I'd consider this: def collect_data(src=None, out=None): if src is None: src = sys.stdin if out is None: out = sys.stdout ostdin = sys.stdin sys.stdin = src ostdout = sys.stdout sys.stdout = out ret = {} ret['first'] = input("Enter your first name: ") ... etc ... sys.stdout = ostdout sys.stdin = ostdin Note that this is not thread safe because sys.stdin is a global, but it should work for testing. Anyway, perhap that gives you some way forward. Cheers, Cameron Simpson From anshu.kumar726 at gmail.com Sun Oct 11 11:00:03 2015 From: anshu.kumar726 at gmail.com (Anshu Kumar) Date: Sun, 11 Oct 2015 14:30:03 +0530 Subject: [Tutor] python certifications Message-ID: Hi All, I have been using python for a year now and want to certify my skill. May I know what are the certifications for python? Thanks and Regards, Anshu From mikiozen at gmail.com Sun Oct 11 14:31:41 2015 From: mikiozen at gmail.com (TJ Nelson) Date: Sun, 11 Oct 2015 08:31:41 -0400 Subject: [Tutor] python certifications In-Reply-To: References: Message-ID: There is no formal python certification other then courses with certification of completion such as uw.edu or coursera. If you are into infosec there is also http://www.securitytube-training.com/online-courses/securitytube-python-scripting-expert/index.html. But i think your best bet is your github account being the way to show people your proficiency. On Sun, Oct 11, 2015 at 5:00 AM, Anshu Kumar wrote: > Hi All, > > I have been using python for a year now and want to certify my skill. > > May I know what are the certifications for python? > > Thanks and Regards, > Anshu > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From akleider at sonic.net Sun Oct 11 18:29:56 2015 From: akleider at sonic.net (Alex Kleider) Date: Sun, 11 Oct 2015 09:29:56 -0700 Subject: [Tutor] how to unittest cli input In-Reply-To: <20151011011054.GA40283@cskk.homeip.net> References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> <20151011011054.GA40283@cskk.homeip.net> Message-ID: On 2015-10-10 18:10, Cameron Simpson wrote: On 10Oct2015 17:41, Alex Kleider wrote: I'm tOn 2015-10-10 18:10, Cameron Simpson wrote: On 10Oct2015 17:41, Alex Kleider wrote: I'm trying to follow a test driven development paradigm (using unittest) but can't figure out how to test functions that collect info from the command line such as the following. Aside: I'd say "the standard input" , not "the command line"; to me the latter connotes to command line arguments fro sys.argv. Point well taken! stdin it is. Ben suggested I should have used the term "interactive" which certainly fits well. Anyway, ... .................. However, you'r eusing input(), which unconditionally uses stdin and stdout. In that circumstance I'd consider this: def collect_data(src=None, out=None): if src is None: src = sys.stdin if out is None: out = sys.stdout ostdin = sys.stdin sys.stdin = src ostdout = sys.stdout sys.stdout = out ret = {} ret['first'] = input("Enter your first name: ") ... etc ... sys.stdout = ostdout sys.stdin = ostdin Note that this is not thread safe because sys.stdin is a global, but it should work for testing. Anyway, perhap that gives you some way forward. Yes indeed, and thank you for your input. Here's where I'm going with your suggestion: # collect.py test_data = 'test_src.txt' def data_collection_wrapper(collect, source=None): """ """ if source: ostdin = sys.stdin ostdout = sys.stdout src = open(source, 'r') sys.stdin = src out = open('/dev/null', 'w') # Dump the prompts. sys.stdout = out ret = collect() if source: src.close() out.close() sys.stdin = ostdin sys.stdout = ostdout return ret def collect_data(): ret = {} ret['first'] = input("Enter your first name: ") ret['last'] = input("Enter your last name: ") ret['phone'] = input("Your mobile phone #: ") return ret def main(): print(collect_data()) # < check that user input works # then check that can test can be automated > print(data_collection_wrapper(collect_data, src=test_data)) if __name__ == "__main__": main() Perhaps data_collection_wrapper could be made into a decorator (about which I am still pretty naive.) It'll take more studying on my part before I'll be able to implement Ben's suggestion. Alex ps I was tempted to change the "Subject:" to remove 'cli' and replace it with 'interactive' but remember many admonitions to not do that so have left it as is. From __peter__ at web.de Sun Oct 11 20:11:14 2015 From: __peter__ at web.de (Peter Otten) Date: Sun, 11 Oct 2015 20:11:14 +0200 Subject: [Tutor] how to unittest cli input References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> <20151011011054.GA40283@cskk.homeip.net> Message-ID: Alex Kleider wrote: > It'll take more studying on my part before I'll be able to implement > Ben's suggestion. I find Ben's example instructive, but when you're just starting you might prefer a simpler approach: import unittest from unittest import mock import collect class TestCollectData(unittest.TestCase): def test(self): with mock.patch( "builtins.input", side_effect=["foo", "bar", "baz"]): self.assertEqual( collect.collect_data(), dict(first="foo", last="bar", phone="baz")) if __name__ == "__main__": unittest.main() with mock.patch("builtins.input, side_effect=[...]): ... temporarily replaces the built-in input() with a function that returns the first item in the side_effect list on the first call, then the second, and so on, something you could do by hand, only less conveniently: >>> def input_many(): # example function; accumulate strings until "" ... result = [] ... while True: ... item = input() ... if item == "": break ... result.append(item) ... return result ... >>> input_many() foo bar ['foo', 'bar'] Works ;) Now let's change input() to something that returns "one", then "two", then "": >>> import builtins >>> _input = builtins.input >>> try: ... builtins.input = lambda items=iter(["one", "two", ""]): next(items) ... input_many() ... finally: ... builtins.input = _input ... ['one', 'two'] From nymcity at yahoo.com Sun Oct 11 23:22:06 2015 From: nymcity at yahoo.com (Nym City) Date: Sun, 11 Oct 2015 21:22:06 +0000 (UTC) Subject: [Tutor] Custom Function that Takes argument In-Reply-To: References: Message-ID: <1148163305.2090509.1444598526135.JavaMail.yahoo@mail.yahoo.com> Thank you for your feedback. I modified the code to reflect your suggestion and it worked. Now, I want to take it to the next level when I prompt the user to make a selection from a list of options and based on their input certain part of the code would execute. Here is the revised code:(site: https://locu.com/) import urllib2 import json locu_api = 'redacted' ans=True while ans: ??? print (""" ??? 1.Search by City ??? 2.Search by State ??? 3.Search by Zip ??? 4.Exit/Quit ??? """) ??? ans=raw_input("What would you like to do? ") ??? if ans=="1": ????? print("\n Enter City") ??? elif ans=="2": ????? print("\n Search by State") ??? elif ans=="3": ????? print("\n Search by Zip") ??? elif ans=="4": ????? print("\n Goodbye") ??? elif ans !="": ????? print("\n Not Valid Choice Try again") # city = input_city = raw_input('Please enter your city: ') # region = input_region = raw_input('Please enter your state: ') # zip = raw_input('What is your zip: ') # def locu_search(query): #???? api_key = locu_api #???? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key #???? locality = query.replace(' ', '%20') #???? final_url = url + '&locality=' + locality + "&category=restaurant" #???? jason_obj = urllib2.urlopen(final_url) #???? data = json.load(jason_obj) #???? for item in data['objects']: #???????? print item['name'], item['phone'], item['street_address'] # # def region_search(query): #???? api_key = locu_api #???? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key #???? region = query.replace(' ', '%20') #???? final_url = url + '®ion=' + region + "&category=restaurant" #???? jason_obj = urllib2.urlopen(final_url) #???? data = json.load(jason_obj) #???? for item in data['objects']: #???????? print item['name'], item['phone'], item['street_address'], item['locality'] # # # def zip_search(query): # #???? api_key = locu_api # #???? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key # #???? zip = query.replace(' ', '%20') # #???? final_url = url + '&zip=' + zip + "&category=restaurant" # #???? jason_obj = urllib2.urlopen(final_url) # #???? data = json.load(jason_obj) # #???? for item in data['objects']: # #???????? print item['name'], item['phone'], item['street_address'], item['categories'] # # # print zip_search(zip) --------------------------------------------------------------------------------------------------------------------- The part that is not working is the initial prompt for selection. The program prompts the user to make a selection, however it is not registering that selection rather repeats the prompt. Hope my question make sense. Please let me know what I am missing. Thank you.?Thank you. On Monday, September 28, 2015 9:03 PM, Alan Gauld wrote: On 29/09/15 00:45, Nym City via Tutor wrote: > I am learning how to create custom functions and watched the > tutorial online that uses API for locu Since most folks here probably don't know locu you should maybe give us a URL. Then we can know what it is you are talking about. > I cannot figure out how to prompt a user to input their zip > code and use that information against the function. The normal way is to pass it in as a parameter of the function: def myfunc(aZipCode): ? ? print aZipCode zip = raw_input('What is your zip: ') myfunc(zip) > import urllib2 > import json > > locu_api = 'not included here for obvious reasons' > zip = raw_input('What is your zip: ') > > def zip_search(query): >? ? ? api_key = locu_api >? ? ? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key >? ? ? zip = query.replace(' ', '%20') >? ? ? final_url = url + '&zip=' + zip + "&category=restaurant" >? ? ? jason_obj = urllib2.urlopen(final_url) >? ? ? data = json.load(jason_obj) >? ? ? for item in data['objects']: >? ? ? ? ? print item['name'], item['phone'], item['street_address'], item['categories'] > > print zip_search(zip_search()) Here you are passing the results of your own function in as an argument to your function. That should give an error since the inner call has no argument and the function is looking for one. You need to pass in your query string: print zip_search(zip) Always post any errors you get it helps us help 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 _______________________________________________ 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 Sun Oct 11 23:52:59 2015 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 12 Oct 2015 08:52:59 +1100 Subject: [Tutor] how to unittest cli input In-Reply-To: References: Message-ID: <20151011215259.GA22420@cskk.homeip.net> On 11Oct2015 09:29, Alex Kleider wrote: >On 2015-10-10 18:10, Cameron Simpson wrote: > However, you'r eusing input(), which unconditionally uses stdin and > stdout. In that circumstance I'd consider this: >[... temporarily replace stdin and stdout with test data ...] > >Yes indeed, and thank you for your input. >Here's where I'm going with your suggestion: >[...] >test_data = 'test_src.txt' > >def data_collection_wrapper(collect, source=None): > """ > """ > if source: Minor remark: I would write "if src is not None:". In principle the empty string is also "falsey" like None, making your plain "if src:" slightly unreliable. Be precise! > ostdin = sys.stdin > ostdout = sys.stdout > src = open(source, 'r') > sys.stdin = src > out = open('/dev/null', 'w') # Dump the prompts. > sys.stdout = out > > ret = collect() > > if source: > src.close() > out.close() > sys.stdin = ostdin > sys.stdout = ostdout > > return ret > > >def collect_data(): > ret = {} > ret['first'] = input("Enter your first name: ") > ret['last'] = input("Enter your last name: ") > ret['phone'] = input("Your mobile phone #: ") > return ret That looks like what I had in mind. If you expect to do this with several functions you could write a context manager to push new values for stdin and stdout, call a function and restore. The "contextlib" stdlib module provides a convenient way to write trivial context managers using the "@contextmanager" decorator, which wraps a generator function which does the before/after steps. Have a read. I'd be inclined to write something like this (untested): import sys from contextlib import contextmanager @contextmanager def temp_stdinout(src, dst): ostdin = sys.stdin ostdout = sys.stdout sys.stdin = src sys.stdout = dst yield None sys.stdin = ostdin sys.stdout = ostdout and then in your test code: with open(source) as src: with open('/dev/null', 'w') as dst: with temp_stdinout(src, dst): ret = collect() This has several benefits. Primarily, a context manager's "after" code _always_ runs, even if an exception is raise in the inner section. This means that the files are always closed, and the old stdin and stdout always restored. This is very useful. You'll notice also that an open file is a context manager which can be used with the "with" statement: it always closes the file. You also asked (off list) what I meant by parameterisation. I mean that some of your difficult stems from "collect_data" unconditionally using stdin and stdout< and that you can make it more flexible by supplying the input and output as paramaters to the function. Example (not finished): def collect_data(src, dst): ret = {} ret['first'] = input("Enter your first name: ") ret['last'] = input("Enter your last name: ") ret['phone'] = input("Your mobile phone #: ") return ret Now, the input() builtin always uses stdin and stdout, but it is not hard to write your own: def prompt_for(prompt, src, dst): dst.write(prompt) dst.flush() return src.readline() and use it in collect_data: def collect_data(src, dst): ret = {} ret['first'] = prompt_for("Enter your first name: ", src, dst) ret['last'] = prompt_for("Enter your last name: ", src, dst) ret['phone'] = prompt_for("Your mobile phone #: ", src, dst) return ret You can also make src and dst optional, falling back to stdin and stdout: def collect_data(src=None, dst=None): if src is None: src = sys.stdin if dst is None: dst = sys.stdout ret = {} ret['first'] = prompt_for("Enter your first name: ", src, dst) ret['last'] = prompt_for("Enter your last name: ", src, dst) ret['phone'] = prompt_for("Your mobile phone #: ", src, dst) return ret Personally I would resist that in this case because the last thing you really want in a function is for it to silently latch onto your input/output if you forget to call it with all its arguments/parameters. Default are better for things that do not have side effects. >def main(): > print(collect_data()) # < check that user input works > # then check that can test can be automated > > print(data_collection_wrapper(collect_data, > src=test_data)) > >if __name__ == "__main__": > main() > >Perhaps data_collection_wrapper could be made into a decorator (about >which I am still pretty naive.) > >It'll take more studying on my part before I'll be able to implement >Ben's suggestion. > >Alex >ps I was tempted to change the "Subject:" to remove 'cli' and replace >it with 'interactive' but remember many admonitions to not do that so >have left it as is. Best to leave these things as they are unless the topic totally changes. Then I tend to adjust the Subject: to be: Subject: very different topic (was: old topic) presuming that it is still the same discussion. Cheers, Cameron Simpson From alan.gauld at btinternet.com Mon Oct 12 00:25:18 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 11 Oct 2015 23:25:18 +0100 Subject: [Tutor] Custom Function that Takes argument In-Reply-To: <1148163305.2090509.1444598526135.JavaMail.yahoo@mail.yahoo.com> References: <1148163305.2090509.1444598526135.JavaMail.yahoo@mail.yahoo.com> Message-ID: <561AE1CE.8030108@btinternet.com> On 11/10/15 22:22, Nym City wrote: > import urllib2 > import json > > locu_api = 'redacted' > > ans=True > while ans: > print (""" > 1.Search by City > 2.Search by State > 3.Search by Zip > 4.Exit/Quit > """) > ans=raw_input("What would you like to do? ") > if ans=="1": > print("\n Enter City") > elif ans=="2": > print("\n Search by State") > elif ans=="3": > print("\n Search by Zip") > elif ans=="4": > print("\n Goodbye") > elif ans !="": > print("\n Not Valid Choice Try again") > > Note that you never set ans to any false value so it will keep on looping until you do (by entering an empty string). You probably need to use break to exit the loop whenb you get valid input. > # def locu_search(query): > # api_key = locu_api > # url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key > # locality = query.replace(' ', '%20') > # final_url = url + '&locality=' + locality + "&category=restaurant" Note that you should not try to build the query string yourself, there are functions in the standard library that will do most of the work and they will be more reliable than anythong you can write yourself. For example look at the urllib module (for 2.7, its the urlib.parse module in v3) which contains several utility functions such as quote() and urlencode() -- 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 fast_primes at hotmail.com Mon Oct 12 06:15:00 2015 From: fast_primes at hotmail.com (Fast Primes) Date: Mon, 12 Oct 2015 00:15:00 -0400 Subject: [Tutor] Can one use python to concatenate n media files? Message-ID: If so, could someone present an example? Thanks. Sent from Mail for Windows 10 From emile at fenx.com Mon Oct 12 16:21:57 2015 From: emile at fenx.com (Emile van Sebille) Date: Mon, 12 Oct 2015 07:21:57 -0700 Subject: [Tutor] Can one use python to concatenate n media files? In-Reply-To: References: Message-ID: On 10/11/2015 9:15 PM, Fast Primes wrote: > > If so, could someone present an example? target = open(target,'wb') for source in mediafilelist: target.write(open(source,'rb').read()) But you probably want something different anyway. Emile From sjeik_appie at hotmail.com Mon Oct 12 18:12:57 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Mon, 12 Oct 2015 16:12:57 +0000 Subject: [Tutor] 0 > "0" --> is there a "from __future__ import to make this raise a TypeError? Message-ID: Hi, In Python 2 one can do silly apple-pear comparisons such as 0> "0".*) "CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don?t support proper comparison are ordered by their address.". In Python3 this has been fixed (it raises a TypeError). Is there a way to emulate this behavior in Python 2? *)http://stackoverflow.com/questions/3270680/how-does-python-compare-string-and-int Thank you! Albert-Jan From emile at fenx.com Mon Oct 12 18:25:00 2015 From: emile at fenx.com (Emile van Sebille) Date: Mon, 12 Oct 2015 09:25:00 -0700 Subject: [Tutor] 0 > "0" --> is there a "from __future__ import to make this raise a TypeError? In-Reply-To: References: Message-ID: On 10/12/2015 9:12 AM, Albert-Jan Roskam wrote: > Hi, > > > In Python 2 one can do silly apple-pear comparisons such as 0> "0".*) "CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don?t support proper comparison are ordered by their address.". In Python3 this has been fixed (it raises a TypeError). Is there a way to emulate this behavior in Python 2? > > > > *)http://stackoverflow.com/questions/3270680/how-does-python-compare-string-and-int > See if implementing __cmp__ gets you what you're looking for. See http://www.rafekettler.com/magicmethods.html#comparisons for more info. Emile From akleider at sonic.net Mon Oct 12 19:37:51 2015 From: akleider at sonic.net (Alex Kleider) Date: Mon, 12 Oct 2015 10:37:51 -0700 Subject: [Tutor] how to unittest cli input In-Reply-To: <20151011215259.GA22420@cskk.homeip.net> References: <20151011215259.GA22420@cskk.homeip.net> Message-ID: <4ce68207ca28ed973438cbe2c58b7b7a@sonic.net> On 2015-10-11 14:52, Cameron Simpson wrote: > Minor remark: I would write "if src is not None:". In principle the > empty string is also "falsey" like None, making your plain "if src:" > slightly unreliable. Be precise! 'precise' is good! Any comments about when/if to use 'if src != None:' vs 'if src is not None:'? (or 'if src == None:' vs 'if src is None:') From alan.gauld at btinternet.com Mon Oct 12 20:12:39 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 12 Oct 2015 19:12:39 +0100 Subject: [Tutor] Can one use python to concatenate n media files? In-Reply-To: References: Message-ID: On 12/10/15 05:15, Fast Primes wrote: > > If so, could someone present an example? Yes, and Emile has shown how for a trivial, pure binary case. But to make the catenation sensible you need to know the file type. Many media files hold the actual media data inside an envelope of header information. To do a sensible job you need to know where the data starts and how you want to process the meta data in the headers. It's all possible and helper modules exist for many types of file/metadata. But without knowing the types of media you are trying to catenate its effectively impossible to give working examples. And if you want to catenate different types of media file (eg a .WMA, an .MP3 and a .AU) then you also need to do data conversions etc. Its all possible but its mostly non trivial. -- 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.Aldrich at EMEA.NEC.COM Mon Oct 12 16:58:12 2015 From: David.Aldrich at EMEA.NEC.COM (David Aldrich) Date: Mon, 12 Oct 2015 14:58:12 +0000 Subject: [Tutor] How to read all integers from a binary file? In-Reply-To: References: <41302A7145AC054FA7A96CFD03835A0A0B9EAC21@EX10MBX02.EU.NEC.COM> Message-ID: <41302A7145AC054FA7A96CFD03835A0A0B9EB6FB@EX10MBX02.EU.NEC.COM> > data = array.array("i", inf.read()) Thanks for all the answers to my question. I used the array method in the end. Best regards David From David.Aldrich at EMEA.NEC.COM Mon Oct 12 16:55:43 2015 From: David.Aldrich at EMEA.NEC.COM (David Aldrich) Date: Mon, 12 Oct 2015 14:55:43 +0000 Subject: [Tutor] Guidance on using custom exceptions please Message-ID: <41302A7145AC054FA7A96CFD03835A0A0B9EB6D8@EX10MBX02.EU.NEC.COM> Hi Consider a 'send' method that sends a message to another system via a socket. This method will wait for a response before returning. There are two possible error conditions: 1) Timeout - i.e. no response received 2) Illegal response received I need to communicate these errors to the caller of send(). So far I have just raised a RuntimeError exception for both errors, and stated what happened like this: raise RuntimeError("Message timeout") That's fine if the caller just wants to print the error but not so good if the code needs to act differently according to which error condition occurred. So, my question is, what's the pythonic way of doing this? Should I subclass RuntimeError for each possible error condition? E.g.: class MessageTimeoutError(RuntimeError): pass class IllegalResponseError(RuntimeError): pass Best regards David From sjeik_appie at hotmail.com Mon Oct 12 22:24:36 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Mon, 12 Oct 2015 20:24:36 +0000 Subject: [Tutor] 0 > "0" --> is there a "from __future__ import to make this raise a TypeError? In-Reply-To: References: , Message-ID: ---------------------------------------- > To: tutor at python.org > From: emile at fenx.com > Date: Mon, 12 Oct 2015 09:25:00 -0700 > Subject: Re: [Tutor] 0> "0" --> is there a "from __future__ import to make this raise a TypeError? > > On 10/12/2015 9:12 AM, Albert-Jan Roskam wrote: >> Hi, >> >> >> In Python 2 one can do silly apple-pear comparisons such as 0> "0".*) "CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don?t support proper comparison are ordered by their address.". In Python3 this has been fixed (it raises a TypeError). Is there a way to emulate this behavior in Python 2? >> >> >> >> *)http://stackoverflow.com/questions/3270680/how-does-python-compare-string-and-int >> > > See if implementing __cmp__ gets you what you're looking for. > > See http://www.rafekettler.com/magicmethods.html#comparisons for more info. > > Emile Hi Emille, Maybe like so? Is it possible to call __cmp__ wiithout the need to make an instance? I would find it nicer if I could do Cmp(42) == "42". Also, the two if/elifs don't feel quite right/generic. # -*- coding: utf-8 -*-. class Cmp(object): ??? """Compare objects the Python 3 way: no apple-pear comparisons allowed! ??? ???>>> x = Cmp()? # doctest: +IGNORE_EXCEPTION_DETAIL ???>>> x(42) == "42" ??? Traceback (most recent call last): ??? ... ??? TypeError ???>>> x(42) == 42 ??? True ???>>> x(42) == 42.1 ??? False ???>>> x("42")> 0 ??? Traceback (most recent call last): ??? ... ??? TypeError ??? """ ??? def __call__(self, x): ??????? self.x = x ??????? return self ??? def __cmp__(self, y): ??????? #print "__cmp__" ??????? self.y = y ??????? if isinstance(self.x, (str, unicode)) and hasattr(self.y, "__int__"): ??????????? raise TypeError ??????? elif isinstance(self.y, (str, unicode)) and hasattr(self.x, "__int__"): ??????????? raise TypeError ??????? return -1 if self.x < self.y else 0 if self.x == self.y else 1 if __name__ == "__main__": ??? import doctest ??? doctest.testmod() From oscar.j.benjamin at gmail.com Mon Oct 12 22:37:43 2015 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Mon, 12 Oct 2015 20:37:43 +0000 Subject: [Tutor] 0 > "0" --> is there a "from __future__ import to make this raise a TypeError? In-Reply-To: References: Message-ID: On Mon, 12 Oct 2015 17:15 Albert-Jan Roskam wrote: Hi, In Python 2 one can do silly apple-pear comparisons such as 0> "0".*) "CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don?t support proper comparison are ordered by their address.". In Python3 this has been fixed (it raises a TypeError). Is there a way to emulate this behavior in Python 2? Why do you want to? This kind of thing is nice to have when it's there by default since it can help pick up errors. When it's not there that's unfortunate which is why this was changed in Python 3 but it's not really essential. Most of the time you won't mix strings and ints unless it's a mistake. Are you worried about making mistakes? Why not just test your code under Python 3 if so? -- Oscar From ben+python at benfinney.id.au Tue Oct 13 00:17:44 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Tue, 13 Oct 2015 09:17:44 +1100 Subject: [Tutor] how to unittest cli input References: <20151011215259.GA22420@cskk.homeip.net> <4ce68207ca28ed973438cbe2c58b7b7a@sonic.net> Message-ID: <85r3kzu3xz.fsf@benfinney.id.au> Alex Kleider writes: > Any comments about when/if to use 'if src != None:' vs 'if src is not > None:'? Express your intention in the code. If you want to express ?is this value the ?None? singleton??, compare identity with ?is?/?is not?. (This is what you almost always mean when comparing to ?None?; I know of no useful exceptions to this.) If you want to express ?is this value possibly different from ?None? but compares as equal??, compare for equality with ?==?/?!=?. (As can be guessed from my description, I don't know of any good reason this would be preferred for ?None?.) The distinction gets to the issue of object identity, as distinct from value equality. You don't need to know the details of that quite yet. Just know that you can choose whether to allow an object to declare it is equal to some other value, without actually being that same value. That's what you want in most comparisons (use ?==?), but there is a large minority of comparisons where you instead want to know whether an object *is* some other object (use ?is?). -- \ ?Pinky, are you pondering what I'm pondering?? ?Wuh, I think | `\ so, Brain, but how will we get three pink flamingos into one | _o__) pair of Capri pants?? ?_Pinky and The Brain_ | Ben Finney From steve at pearwood.info Tue Oct 13 01:19:33 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 13 Oct 2015 10:19:33 +1100 Subject: [Tutor] how to unittest cli input In-Reply-To: <4ce68207ca28ed973438cbe2c58b7b7a@sonic.net> References: <20151011215259.GA22420@cskk.homeip.net> <4ce68207ca28ed973438cbe2c58b7b7a@sonic.net> Message-ID: <20151012231929.GM28222@ando.pearwood.info> On Mon, Oct 12, 2015 at 10:37:51AM -0700, Alex Kleider wrote: > Any comments about when/if to use 'if src != None:' vs 'if src is not > None:'? > (or 'if src == None:' vs 'if src is None:') Short answer: always compare to None using `is` or `is not`. Long answer: If you want to check for src being specifically None, then use `src is None`, since None is the only object that can be identical to None. If you want to check for some random object that merely compares equal to None (and why would you do that?) then use `src == None`, since that will give src a chance to decide whether or not it compares equal to None. For built-in types (ints, floats, strings, etc.) there's no practical difference, but as soon as custom objects may be involved, then you don't know whether you might get some custom object that for reasons of its own will compare equal to None: class Falsey: def __eq__(self, other): return (not other) Also, `is` comparisons are faster than `==` comparisons, not that this will usually matter. -- Steve From steve at pearwood.info Tue Oct 13 01:37:01 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 13 Oct 2015 10:37:01 +1100 Subject: [Tutor] Guidance on using custom exceptions please In-Reply-To: <41302A7145AC054FA7A96CFD03835A0A0B9EB6D8@EX10MBX02.EU.NEC.COM> References: <41302A7145AC054FA7A96CFD03835A0A0B9EB6D8@EX10MBX02.EU.NEC.COM> Message-ID: <20151012233700.GN28222@ando.pearwood.info> On Mon, Oct 12, 2015 at 02:55:43PM +0000, David Aldrich wrote: > Hi > > Consider a 'send' method that sends a message to another system via a > socket. This method will wait for a response before returning. There > are two possible error conditions: [...] > So, my question is, what's the pythonic way of doing this? Should I > subclass RuntimeError for each possible error condition? E.g.: > > class MessageTimeoutError(RuntimeError): pass > class IllegalResponseError(RuntimeError): pass I don't think you should be subclassing RuntimeError at all. I'm not quite sure what exception you should subclass, but I am confident it shouldn't be RuntimeError. Help on class RuntimeError in module exceptions: class RuntimeError(StandardError) Unspecified run-time error. Since you are working with sockets, I think a socket error might be most useful: import socket # which I expect you are already doing class MessageTimeoutError(socket.error): pass class IllegalResponseError(socket.error): pass Or possibly inherit from the same exception class that socket.error inherits from: IOError. I'm not certain that you actually need MessageTimeoutError since the socket module itself already defines a socket.timeout error that will be raised on a timeout. Just re-use that. -- Steve From nymcity at yahoo.com Tue Oct 13 01:32:26 2015 From: nymcity at yahoo.com (Nym City) Date: Mon, 12 Oct 2015 23:32:26 +0000 (UTC) Subject: [Tutor] Custom Function that Takes argument In-Reply-To: <561AE1CE.8030108@btinternet.com> References: <561AE1CE.8030108@btinternet.com> Message-ID: <385854698.2666030.1444692746969.JavaMail.yahoo@mail.yahoo.com> Thank you for your response. I updated the first portion of my code to include breaks: import urllib2 import json locu_api = 'redacted' ans=True while ans: ??? print (""" ??? 1.Search by City ??? 2.Search by Region (State Abbreviation) ??? 3.Search by Zip ??? 4.Exit/Quit ??? """) ??? ans=raw_input("What would you like to do? ") ??? if ans=="1": ????? locality = raw_input("\nEnter City ") ????? break ??? elif ans=="2": ??????? region = raw_input("\n Search by State ") ??????? break ??? elif ans=="3": ??????? zip = raw_input("\n Search by Zip ") ??????? break ??? elif ans=="4": ????? print("\n Goodbye") ????? break def locu_search(query): ??? api_key = locu_api ??? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key ??? locality = query.replace(' ', '%20') ??? final_url = url + '&locality=' + locality + "&category=restaurant" ??? jason_obj = urllib2.urlopen(final_url) ??? data = json.load(jason_obj) ??? for item in data['objects']: ??????? print item['name'], item['phone'], item['street_address'] def region_search(query): ??? api_key = locu_api ??? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key ??? region = query.replace(' ', '%20') ??? final_url = url + '®ion=' + region + "&category=restaurant" ??? jason_obj = urllib2.urlopen(final_url) ??? data = json.load(jason_obj) ??? for item in data['objects']: ??????? print item['name'], item['phone'], item['street_address'], item['locality'], item['website_url'] def zip_search(query): ??? api_key = locu_api ??? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key ??? zip = query.replace(' ', '%20') ??? final_url = url + '&zip=' + zip + "&category=restaurant" ??? jason_obj = urllib2.urlopen(final_url) ??? data = json.load(jason_obj) ??? for item in data['objects']: ??????? print item['name'], item['phone'], item['street_address'], item['categories'], item['website_url'] def non_empty_variable(varibles): ??? for varible in varibles: ??????? if varible != "": ??????????? print varible varibles = [locu_search(locality), region_search(region), zip_search(zip)] --------------------------------- With the above updates, the user prompts are working fine now. Thanks! The issue that I am trying to solve now is print the final result.? The use case is that by not knowing which of the 4 options the user will select, i need a way to figure out which selection user made, run it against the appropriate query and than print out the result.? My thought process is to narrow down the user selection by figuring out which of the 4 choices is not blank. To do this I created this: def non_empty_variable(varibles): ??? for varible in varibles: ??????? if varible != "": ??????????? print varible varibles = [locu_search(locality), region_search(region), zip_search(zip)] ______________________________I think the above should work but I get traceback error: Traceback (most recent call last): ? File "C:/Users/dell/Documents/Python/MyProject/API_Projects/locu/locuAPI.py", line 70, in ??? varibles = [locu_search(locality), region_search(region), zip_search(zip)] NameError: name 'locality' is not defined --------The error points back to where this is: varibles = [locu_search(locality), region_search(region), zip_search(zip)] I don't understand why Python thinks that locality (and others) are not defined when I defined them at the very beginning. ___________________________After I get this new issue resolved, I will go back and review urllib query functions. ?Thank you. On Sunday, October 11, 2015 6:25 PM, Alan Gauld wrote: On 11/10/15 22:22, Nym City wrote: > import urllib2 > import json > > locu_api = 'redacted' > > ans=True > while ans: >? ? print (""" >? ? 1.Search by City >? ? 2.Search by State >? ? 3.Search by Zip >? ? 4.Exit/Quit >? ? """) >? ? ans=raw_input("What would you like to do? ") >? ? if ans=="1": >? ? ? print("\n Enter City") >? ? elif ans=="2": >? ? ? print("\n Search by State") >? ? elif ans=="3": >? ? ? print("\n Search by Zip") >? ? elif ans=="4": >? ? ? print("\n Goodbye") >? ? elif ans !="": >? ? ? print("\n Not Valid Choice Try again") > > Note that you never set ans to any false value so it will keep on looping until you do (by entering an empty string). You probably need to use break to exit the loop whenb you get valid input. > # def locu_search(query): > #? ? api_key = locu_api > #? ? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key > #? ? locality = query.replace(' ', '%20') > #? ? final_url = url + '&locality=' + locality + "&category=restaurant" Note that you should not try to build the query string yourself, there are functions in the standard library that will do most of the work and they will be more reliable than anythong you can write yourself. For example look at the urllib module (for 2.7, its the urlib.parse module in v3) which contains several utility functions such as quote() and urlencode() -- 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 Tue Oct 13 01:59:01 2015 From: cs at zip.com.au (Cameron Simpson) Date: Tue, 13 Oct 2015 10:59:01 +1100 Subject: [Tutor] Guidance on using custom exceptions please In-Reply-To: <20151012233700.GN28222@ando.pearwood.info> References: <20151012233700.GN28222@ando.pearwood.info> Message-ID: <20151012235901.GA54587@cskk.homeip.net> On 13Oct2015 10:37, Steven D'Aprano wrote: >On Mon, Oct 12, 2015 at 02:55:43PM +0000, David Aldrich wrote: >> Consider a 'send' method that sends a message to another system via a >> socket. This method will wait for a response before returning. There >> are two possible error conditions: >[...] >> So, my question is, what's the pythonic way of doing this? Should I >> subclass RuntimeError for each possible error condition? E.g.: >> >> class MessageTimeoutError(RuntimeError): pass >> class IllegalResponseError(RuntimeError): pass > >I don't think you should be subclassing RuntimeError at all. I'm not >quite sure what exception you should subclass, but I am confident it >shouldn't be RuntimeError. > >Help on class RuntimeError in module exceptions: > >class RuntimeError(StandardError) > Unspecified run-time error. I tend to use RuntimeError for program logic errors (code paths that shoudn't happen, like not handling an option combination). I would not use it for this. >Since you are working with sockets, I think a socket error might be most >useful: > >import socket # which I expect you are already doing > >class MessageTimeoutError(socket.error): pass >class IllegalResponseError(socket.error): pass > >Or possibly inherit from the same exception class that socket.error >inherits from: IOError. I have mixed feeling about this; I feel that socket.error or IOError should reflect actual OS level or IO subsystem errors, not higher level program discrepancies such as invalid packet data. I would be included to subclass StandardError. Antipattern example: I discovered yesterday that PILLOW raises OSError when it doesn't recognise an image file's content. I consider that a bad choice; I'd prefer ValueError probably - there's been no OS level failure like lack of permission to open the file. On that basis, I recommend either just raising a ValueError for an invalid packet or subclassing it. >I'm not certain that you actually need MessageTimeoutError since the >socket module itself already defines a socket.timeout error that will be >raised on a timeout. Just re-use that. That seems reasonable, if he's using the recv timeout facility. Cheers, Cameron Simpson From alan.gauld at btinternet.com Tue Oct 13 02:30:04 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 13 Oct 2015 01:30:04 +0100 Subject: [Tutor] Custom Function that Takes argument In-Reply-To: <385854698.2666030.1444692746969.JavaMail.yahoo@mail.yahoo.com> References: <561AE1CE.8030108@btinternet.com> <385854698.2666030.1444692746969.JavaMail.yahoo@mail.yahoo.com> Message-ID: <561C508C.9040707@btinternet.com> On 13/10/15 00:32, Nym City wrote: > > ans=raw_input("What would you like to do? ") > if ans=="1": > locality = raw_input("\nEnter City ") > break > elif ans=="2": > region = raw_input("\n Search by State ") > break > elif ans=="3": > zip = raw_input("\n Search by Zip ") > break > elif ans=="4": > print("\n Goodbye") > break > ... The use case is that by not knowing which of the 4 options the > user will select, But you know what they select after they have done it so you need to wait till that point to run the appropriate query. And ans tells you which choice the user made. > NameError: name 'locality' is not defined > > -------- > The error points back to where this is: > > varibles = [locu_search(locality), region_search(region), zip_search(zip)] > > I don't understand why Python thinks that locality (and others) are > not defined when I defined them at the very beginning. > You didn't. You only define them once the user makes a choice. eg. If the ans is 3 then locality and region are not defined. But even if they were (with default values) you don;t want to run all the queries each time. Only run the query selected by the user. So call the query functions in the if/else structure where you set the variables. 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 Tue Oct 13 06:21:23 2015 From: crusier at gmail.com (Crusier) Date: Mon, 12 Oct 2015 21:21:23 -0700 Subject: [Tutor] Beautiful Soup Message-ID: Hi I am using Python 3.4. I am trying to do some web scraping at this moment. I got stuck because there is an IndexError: list index out of range if I put stock_code = (18). My desire output is that the script is able to detect print out the recent price whether it is up, down or unchanged. Attached is the code: import requests from bs4 import BeautifulSoup stock_code = (939) url = ("http://www.etnet.com.hk/www/eng/stocks/realtime/quote.php?code=" + str(stock_code) ) res = requests.get(url).text soup = BeautifulSoup(res, "html.parser") for item in soup.select('#StkDetailMainBox'): if item.select('.up2') == item.select('.up2'): print('Now is trading at UP', item.select('.up2')[0].text) elif item.select('.down2') == item.select('.down2'): print('Now is trading at DOWN', item.select('.down2')[0].text) elif item.select('.unchange2') == item.select('.unchange2'): print('Now is trading at UNCHANGE', item.select('.unchange2')[0].text) print('Change is ', item.select('.Change')[0].text) #for item in soup.select('.styleB'): #print(item.select('.Number')[0].text) From cs at zip.com.au Tue Oct 13 07:13:32 2015 From: cs at zip.com.au (Cameron Simpson) Date: Tue, 13 Oct 2015 16:13:32 +1100 Subject: [Tutor] Beautiful Soup In-Reply-To: References: Message-ID: <20151013051332.GA81016@cskk.homeip.net> On 12Oct2015 21:21, Crusier wrote: >I am using Python 3.4. I am trying to do some web scraping at this moment. >I got stuck because there is an IndexError: list index out of range if I >put stock_code = (18). My desire output is that the script is able to >detect print out the recent price whether it is up, down or unchanged. Just a remark: you write: var = (value) a lot. It's ok, but needless and also slightly prone to turning into a tuple if there's a stray comma. Anyway... It would be helpful to have the exact error message. You say "there is an IndexError: list index out of range", but that can occur in several places in your code. Normally Python will print a stack trace indicating the specific place in your code where the exception occurred. Please always include the complete error message when asking for help. [...] > print('Now is trading at UP', item.select('.up2')[0].text) Everywhere you have [0] you may get an IndexError if the select returns an empty list, because there will be no element 0. > elif item.select('.down2') == item.select('.down2'): I'm curious: how can this test ever be false? Cheers, Cameron Simpson From __peter__ at web.de Tue Oct 13 09:28:28 2015 From: __peter__ at web.de (Peter Otten) Date: Tue, 13 Oct 2015 09:28:28 +0200 Subject: [Tutor] Guidance on using custom exceptions please References: <41302A7145AC054FA7A96CFD03835A0A0B9EB6D8@EX10MBX02.EU.NEC.COM> Message-ID: David Aldrich wrote: > Consider a 'send' method that sends a message to another system via a > socket. This method will wait for a response before returning. There are > two possible error conditions: > > > 1) Timeout - i.e. no response received > > 2) Illegal response received > > I need to communicate these errors to the caller of send(). So far I have > just raised a RuntimeError exception for both errors, and stated what > happened like this: > > raise RuntimeError("Message timeout") > > That's fine if the caller just wants to print the error but not so good if > the code needs to act differently according to which error condition > occurred. > > So, my question is, what's the pythonic way of doing this? Should I > subclass RuntimeError for each possible error condition? E.g.: > > class MessageTimeoutError(RuntimeError): pass > class IllegalResponseError(RuntimeError): pass If you don't want to let the original timeout error bubble up you can create your own little hierarchy of exceptions: class ResponseError(Exception): pass class TimeoutError(ResponseError): pass class BadDataError(ResponseError): pass Then the baseclass of ResponseError doesn't matter much as client code that wants to catch every expected error can catch ResponseError. You can later add subclasses as needed without breaking this catch-all client. From sjeik_appie at hotmail.com Tue Oct 13 15:30:56 2015 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Tue, 13 Oct 2015 13:30:56 +0000 Subject: [Tutor] 0 > "0" --> is there a "from __future__ import to make this raise a TypeError? In-Reply-To: References: , Message-ID: From: oscar.j.benjamin at gmail.com Date: Mon, 12 Oct 2015 20:37:43 +0000 Subject: Re: [Tutor] 0> "0" --> is there a "from __future__ import to make this raise a TypeError? To: sjeik_appie at hotmail.com; tutor at python.org On Mon, 12 Oct 2015 17:15 Albert-Jan Roskam wrote: Hi, In Python 2 one can do silly apple-pear comparisons such as 0> "0".*) "CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don?t support proper comparison are ordered by their address.". In Python3 this has been fixed (it raises a TypeError). Is there a way to emulate this behavior in Python 2? Why do you want to? This kind of thing is nice to have when it's there by default since it can help pick up errors. When it's not there that's unfortunate which is why this was changed in Python 3 but it's not really essential. Most of the time you won't mix strings and ints unless it's a mistake. Are you worried about making mistakes? Why not just test your code under Python 3 if so? -- ======== Hi Oscar Yes, a justified fear of making mistakes. That is, a mistake has already occurred and I don't want it to happen again. I made a comparison with data from two sources: a csv file (reference file) an sqlite database (test data). The csv module will always return str, unless one converts it. The test data were written to sqlite with pandas.to_sql, which (it seems) tries to be helpful by making INTs of everything that looks like ints. I chose sqlite because the real data will be in SQL server, and I hope this would mimic the behavior wrt None, NULL, nan, "", etc. Yesterday I already posted a class with a modified __cmp__ method. Not sure if it came through (I' ve had major problems with DMARC when I was still using yahoo, not yet sure about hotmail) Regards, Albert-Jan From martin at linux-ip.net Tue Oct 13 19:18:08 2015 From: martin at linux-ip.net (Martin A. Brown) Date: Tue, 13 Oct 2015 10:18:08 -0700 Subject: [Tutor] 0 > "0" --> is there a "from __future__ import to make this raise a TypeError? In-Reply-To: References: , Message-ID: Greetings Albert-Jan, I have a suggestion and a comment in this matter. > Yes, a justified fear of making mistakes. That is, a mistake has > already occurred and I don't want it to happen again. Suggestion: Choose a single in-memory representation of your data and make all of your input and output functions perform conversion to appropriate data types. See below for a bit more explanation. > I made a comparison with data from two sources: a csv file > (reference file) an sqlite database (test data). The csv module > will always return str, unless one converts it. The test data were > written to sqlite with pandas.to_sql, which (it seems) tries to be > helpful by making INTs of everything that looks like ints. I chose > sqlite because the real data will be in SQL server, and I hope > this would mimic the behavior wrt None, NULL, nan, "", etc. Comment and explanation: I have been following this thread and I will tell you how I would look at this problem (instead of trying to compare different data types). * It sounds as though you will have several different types of backing stores for your data. You mentioned 1) csv, 2) sqlite, 3) SQL server. Each of these is a different serialization tool. * You also mention comparisons. It seems as though you are comparing data acquired (read into memory) from backing store 1) to data retrieved from 2). If you are reading data into memory, then you are probably planning to compute, process, transmit or display the data. In each case, I'd imagine you are operating on the data (numerically, if they are numbers). I would write a function (or class or module) that can read the data from any of the backing stores you want to use (csv, sqlite, SQL server, punch cards or even pigeon feathers). Each piece of code that reads data from a particular serialization (e.g. sqlite) would be responsible for converting to the in-memory form. Thus, it would not matter where you store the data...once it's in memory, the form or representation you have chosen will be identical. There is the benefit, then, of your code being agnostic (or extensible) to the serialization tool. By the way, did you know that pandas.to_csv() [0] also exists? -Martin [0] http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_csv.html -- Martin A. Brown http://linux-ip.net/ From dyoo at hashcollision.org Tue Oct 13 20:29:00 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 13 Oct 2015 11:29:00 -0700 Subject: [Tutor] 0 > "0" --> is there a "from __future__ import to make this raise a TypeError? In-Reply-To: References: Message-ID: > In Python 2 one can do silly apple-pear comparisons such as 0> "0".*) "CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don?t support proper comparison are ordered by their address.". In Python3 this has been fixed (it raises a TypeError). Is there a way to emulate this behavior in Python 2? I don't think so, at least, not easily. I think that you probably want to move to Python 3 if possible specifically because it cleans up issues like this. There are a few niggling differences between Python 2 and 3, most of them with the same characteristic as the one you're pointing out with loose comparison. (e.g. distinguishing bytes vs strings is another one of the fixes in Python 3). And if you're willing to change the semantics of "<" in Python 2, you're already well on your way to Python 3. From dyoo at hashcollision.org Tue Oct 13 20:41:20 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 13 Oct 2015 11:41:20 -0700 Subject: [Tutor] Guidance on using custom exceptions please In-Reply-To: <41302A7145AC054FA7A96CFD03835A0A0B9EB6D8@EX10MBX02.EU.NEC.COM> References: <41302A7145AC054FA7A96CFD03835A0A0B9EB6D8@EX10MBX02.EU.NEC.COM> Message-ID: On Mon, Oct 12, 2015 at 7:55 AM, David Aldrich wrote: > Hi > > Consider a 'send' method that sends a message to another system via a socket. This method will wait for a response before returning. There are two possible error conditions: > > 1) Timeout - i.e. no response received > > 2) Illegal response received > > I need to communicate these errors to the caller of send(). So far I have just raised a RuntimeError exception for both errors, and stated what happened like this: > > raise RuntimeError("Message timeout") Hi David, According to: https://docs.python.org/3.5/library/exceptions.html you can subclass the "Exception" class. https://docs.python.org/3.5/library/exceptions.html#Exception That's the one that you probably should subclass from, as you're defining your own "non-system-exiting" exception. It's "non-system-exiting" because you expect the caller to have to do some special behavior when receiving such a condition. Use Exception as your base. As Peter Otten describes, you can create your own hierarchy as necessary, but anchor it from Exception first. RuntimeError is for something that doesn't fit any of the other categories used by the Standard Library: https://docs.python.org/3.5/library/exceptions.html#concrete-exceptions As such, it's probably not something you yourself should be using as a subclass. You'd expect to see RuntimeError if something truly unusual is happening within the Python runtime environment. But that's not the case for the exceptions you're describing: timeout and illegal arguments are application-level exceptions, not low-level Python runtime environmental problems. Hope that clears things up! From David.Aldrich at EMEA.NEC.COM Tue Oct 13 15:43:27 2015 From: David.Aldrich at EMEA.NEC.COM (David Aldrich) Date: Tue, 13 Oct 2015 13:43:27 +0000 Subject: [Tutor] Guidance on using custom exceptions please In-Reply-To: References: <41302A7145AC054FA7A96CFD03835A0A0B9EB6D8@EX10MBX02.EU.NEC.COM> Message-ID: <41302A7145AC054FA7A96CFD03835A0A0B9EBE7F@EX10MBX02.EU.NEC.COM> > If you don't want to let the original timeout error bubble up you can create > your own little hierarchy of exceptions: > > class ResponseError(Exception): > pass > > class TimeoutError(ResponseError): > pass > > class BadDataError(ResponseError): > pass > > Then the baseclass of ResponseError doesn't matter much as client code that > wants to catch every expected error can catch ResponseError. You can later > add subclasses as needed without breaking this catch-all client. Thanks for all the answers to my question, they were all helpful. I have one more question, which regards style. Suppose my 'send' method is in its own module: TxControl, along with the custom exceptions: TxControl.py: class MessageTimeoutError(Exception): pass class UndefinedMessageTypeError(Exception): pass def send(msg) etc. Then it seems that an importer of that module must include the module name when referencing the exceptions: import TxControl try: send(msg) except (TxControl.MessageTimeoutError, TxControl.UndefinedMessageTypeError) as err: # Exception processing Including 'TxControl' seems a bit tedious, and is even worse if TxControl imports exceptions from yet another module and allows them to pass up the stack. How would you handle this situation stylistically? David From dyoo at hashcollision.org Tue Oct 13 21:11:43 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 13 Oct 2015 12:11:43 -0700 Subject: [Tutor] how to unittest cli input In-Reply-To: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> Message-ID: On Sat, Oct 10, 2015 at 5:41 PM, Alex Kleider wrote: > """ > I'm trying to follow a test driven development paradigm (using > unittest) but can't figure out how to test functions that collect > info from the command line such as the following. > """ > # collect.py > def collect_data(): > ret = {} > ret['first'] = input("Enter your first name: ") > ret['last'] = input("Enter your last name: ") > ret['phone'] = input("Your mobile phone #: ") > return ret Hi Alex, If we look at collect_data in a funny way, we might see that it is a "function" because it's parameterized by the behavior of the interactive input() function. That means that we can make it a pure function by explicitly treating "input" as a parameter. ######################################### def collect_data(ask): ret = {} ret['first'] = ask("Enter your first name: ") ret['last'] = ask("Enter your last name: ") ret['phone'] = ask("Your mobile phone #: ") return ret ######################################### Making it an explicit parameter means that, when we call it, we can feed it input() as the ask()er: ###################### def main(): print(collect_data(input)) ###################### It also means that we can pass in an ask()er that is non-interactive, which is good for unit tests. For example, here's one we can build up quickly: ###################### def make_ask(f, l, p): d = {'Enter your first name: ' : f, 'Enter your last name: ' : l, 'Your mobile phone #: ' : p} return d.get ###################### What does this do? It gives us an ask that knows how to respond to those questions. For example, at the interactive prompt: ########################################## >>> ask = make_ask('jane', 'doe', '123456789') >>> ask('Enter your first name: ') 'jane' >>> ask('Enter your last name: ') 'doe' ########################################## And now this is a tool we can use for unit testing the behavior of collect_data. That is, we can say: collect_data(make_ask('jane', 'doe', '12345')) and know that we expect the dictionary value: {'first': 'jane', ...} The key is to look at interaction as an explicit parameter of your function: once it's a parameter, then you can pass in custom interactions that are controlled by your unit test. From dyoo at hashcollision.org Tue Oct 13 21:27:11 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 13 Oct 2015 12:27:11 -0700 Subject: [Tutor] Guidance on using custom exceptions please In-Reply-To: <41302A7145AC054FA7A96CFD03835A0A0B9EBE7F@EX10MBX02.EU.NEC.COM> References: <41302A7145AC054FA7A96CFD03835A0A0B9EB6D8@EX10MBX02.EU.NEC.COM> <41302A7145AC054FA7A96CFD03835A0A0B9EBE7F@EX10MBX02.EU.NEC.COM> Message-ID: > Then it seems that an importer of that module must include the module name when referencing the exceptions: > > import TxControl > > try: > send(msg) > except (TxControl.MessageTimeoutError, TxControl.UndefinedMessageTypeError) as err: > # Exception processing > > Including 'TxControl' seems a bit tedious, and is even worse if TxControl imports exceptions from yet another module and allows them to pass up the stack. > > How would you handle this situation stylistically? Stylistically, I'd keep it. This doesn't look bad to me. Certain style guides encourage this, because it becomes easier to see where values are coming from. One definite perk is that it avoids conflicting names from different packages. For example, here's one recommendation: https://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Packages#Packages (Commentary: I've been in a world where imports were unqualified by default, and it was a mess. My programs grew large enough that it made name conflicts almost inevitable. Qualified names are lengthy, but they make that problem a non-issue.) From wolfgang.maier at biologie.uni-freiburg.de Tue Oct 13 23:11:12 2015 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Tue, 13 Oct 2015 23:11:12 +0200 Subject: [Tutor] Guidance on using custom exceptions please In-Reply-To: <41302A7145AC054FA7A96CFD03835A0A0B9EBE7F@EX10MBX02.EU.NEC.COM> References: <41302A7145AC054FA7A96CFD03835A0A0B9EB6D8@EX10MBX02.EU.NEC.COM> <41302A7145AC054FA7A96CFD03835A0A0B9EBE7F@EX10MBX02.EU.NEC.COM> Message-ID: On 13.10.2015 15:43, David Aldrich wrote: > > I have one more question, which regards style. Suppose my 'send' method is in its own module: TxControl, along with the custom exceptions: > > TxControl.py: > > class MessageTimeoutError(Exception): pass > class UndefinedMessageTypeError(Exception): pass > > def send(msg) > etc. > > Then it seems that an importer of that module must include the module name when referencing the exceptions: > > import TxControl > > try: > send(msg) > except (TxControl.MessageTimeoutError, TxControl.UndefinedMessageTypeError) as err: > # Exception processing > > Including 'TxControl' seems a bit tedious, and is even worse if TxControl imports exceptions from yet another module and allows them to pass up the stack. > > How would you handle this situation stylistically? > In simple cases, I would just refer to them as you describe. If things get more complex, you may want to refactor your code into a package anyway, in which case you can define your complete exception hierarchy in __init__.py (or in another dedicated module) and import them from there whenever you need them in other modules. From akleider at sonic.net Tue Oct 13 23:44:51 2015 From: akleider at sonic.net (Alex Kleider) Date: Tue, 13 Oct 2015 14:44:51 -0700 Subject: [Tutor] how to unittest cli input In-Reply-To: References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> Message-ID: <0a2179407277fcd3e1580ae5acf131cf@sonic.net> On 2015-10-13 12:11, Danny Yoo wrote: > ###################### > def make_ask(f, l, p): > d = {'Enter your first name: ' : f, > 'Enter your last name: ' : l, > 'Your mobile phone #: ' : p} > return d.get > ###################### This last line got my attention ("a dict has no such attribute" but rather "it has a 'get' method") but then the light went on: you've created a function that returns a function. So many levels of abstraction! Thanks for making things fall into place. cheers, Alex From cs at zip.com.au Tue Oct 13 23:29:21 2015 From: cs at zip.com.au (Cameron Simpson) Date: Wed, 14 Oct 2015 08:29:21 +1100 Subject: [Tutor] Guidance on using custom exceptions please In-Reply-To: <41302A7145AC054FA7A96CFD03835A0A0B9EBE7F@EX10MBX02.EU.NEC.COM> References: <41302A7145AC054FA7A96CFD03835A0A0B9EBE7F@EX10MBX02.EU.NEC.COM> Message-ID: <20151013212921.GA28894@cskk.homeip.net> On 13Oct2015 13:43, David Aldrich wrote: >Thanks for all the answers to my question, they were all helpful. > >I have one more question, which regards style. Suppose my 'send' method is in its own module: TxControl, along with the custom exceptions: > >TxControl.py: > >class MessageTimeoutError(Exception): pass >class UndefinedMessageTypeError(Exception): pass > >def send(msg) > etc. > >Then it seems that an importer of that module must include the module name when referencing the exceptions: > >import TxControl > >try: > send(msg) >except (TxControl.MessageTimeoutError, TxControl.UndefinedMessageTypeError) as err: > # Exception processing > >Including 'TxControl' seems a bit tedious, and is even worse if TxControl >imports exceptions from yet another module and allows them to pass up the >stack. Without ignoring others' arguments for keeping the full names, you can also go: from TxControl import send, MessageTimeoutError, UndefinedMessageTypeError and just use them unqualified like any other name you might import. The core issue, to me, is: are the exception names nice and descriptive (they look ok to me) and is the module you're using them in not using other exceptions of similar name and purpose (i.e. how confusing might the unqualified named be)? Also bear in mind that you can do this: from TxControl import send as tx_send, MessageTimeoutError as TxTimeoutError, UndefinedMessageTypeError as TxUndefinedMessageType which gets you more descriptive names for local use. If course, if these exceptions are widely used in many contexts (many other code pieces) then you might want to stick with the original names for consistency. Cheers, Cameron Simpson Go not to the elves for counsel, for they will say both no and yes. - Frodo, The Fellowship of the Ring From steve at pearwood.info Wed Oct 14 01:06:19 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 14 Oct 2015 10:06:19 +1100 Subject: [Tutor] 0 > "0" --> is there a "from __future__ import to make this raise a TypeError? In-Reply-To: References: Message-ID: <20151013230619.GC13813@ando.pearwood.info> On Mon, Oct 12, 2015 at 04:12:57PM +0000, Albert-Jan Roskam wrote: > Hi, > > > In Python 2 one can do silly apple-pear comparisons such as 0> "0".*) > "CPython implementation detail: Objects of different types except > numbers are ordered by their type names; objects of the same types > that don?t support proper comparison are ordered by their address.". > In Python3 this has been fixed (it raises a TypeError). Is there a way > to emulate this behavior in Python 2? I don't believe so. You could write your own comparison functions and use those: def gt(a, b): if type(a) is type(b): return a > b raise TypeError if gt(this, that): ... but there's no way to change the behaviour of the comparison operators > etc themselves, nor of list.sort. In hindsight, this should have been a __future__ import, but it's too late now :-( -- Steve From dyoo at hashcollision.org Wed Oct 14 01:06:27 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 13 Oct 2015 16:06:27 -0700 Subject: [Tutor] how to unittest cli input In-Reply-To: <0a2179407277fcd3e1580ae5acf131cf@sonic.net> References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> <0a2179407277fcd3e1580ae5acf131cf@sonic.net> Message-ID: On Tue, Oct 13, 2015 at 2:44 PM, Alex Kleider wrote: > On 2015-10-13 12:11, Danny Yoo wrote: > > >> ###################### >> def make_ask(f, l, p): >> d = {'Enter your first name: ' : f, >> 'Enter your last name: ' : l, >> 'Your mobile phone #: ' : p} >> return d.get >> ###################### > > > This last line got my attention ("a dict has no such attribute" > but rather "it has a 'get' method") > but then the light went on: you've created a function that > returns a function. So many levels of abstraction! Yes. Functions are cool. To use of functions as first-class values is a lot of fun, and you'll get the hang of it once you see the trick a few times. From akleider at sonic.net Wed Oct 14 19:49:47 2015 From: akleider at sonic.net (Alex Kleider) Date: Wed, 14 Oct 2015 10:49:47 -0700 Subject: [Tutor] how to unittest cli input In-Reply-To: <0a2179407277fcd3e1580ae5acf131cf@sonic.net> References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> <0a2179407277fcd3e1580ae5acf131cf@sonic.net> Message-ID: <11c61fce4243b1dcbea64f85939e9087@sonic.net> On 2015-10-13 14:44, Alex Kleider wrote: > On 2015-10-13 12:11, Danny Yoo wrote: > > >> ###################### >> def make_ask(f, l, p): >> d = {'Enter your first name: ' : f, >> 'Enter your last name: ' : l, >> 'Your mobile phone #: ' : p} >> return d.get >> ###################### This is an example of a 'closure' is it not? ak From dyoo at hashcollision.org Wed Oct 14 20:29:42 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 14 Oct 2015 11:29:42 -0700 Subject: [Tutor] how to unittest cli input In-Reply-To: <11c61fce4243b1dcbea64f85939e9087@sonic.net> References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> <0a2179407277fcd3e1580ae5acf131cf@sonic.net> <11c61fce4243b1dcbea64f85939e9087@sonic.net> Message-ID: >>> ###################### >>> def make_ask(f, l, p): >>> d = {'Enter your first name: ' : f, >>> 'Enter your last name: ' : l, >>> 'Your mobile phone #: ' : p} >>> return d.get >>> ###################### > > > This is an example of a 'closure' is it not? Yes, though I try not to use the word "closure" because it's a technical distinction that isn't really that useful for beginners because it focuses on the implementation details. That is, when we say the word "closure", we're emphasizing the fact that it's a combination of code and the data that it needs to resolve the code's free variables. And for this discussion, all I really cared about was that we needed something that knows how to be "called". Anything that distracts from that point is something I'm actively trying to avoid, at least at first. We could try to make the code look clever by doing something like: ################################################ make_ask = lambda f, l, p: (lambda key: {'Enter your first name: ' : f, 'Enter your last name: ' : l, 'Your mobile phone #: ' : p}[key]) ################################################ But this would be death to the point I was trying to make. :P From akleider at sonic.net Wed Oct 14 21:20:31 2015 From: akleider at sonic.net (Alex Kleider) Date: Wed, 14 Oct 2015 12:20:31 -0700 Subject: [Tutor] how to unittest cli input In-Reply-To: References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> <0a2179407277fcd3e1580ae5acf131cf@sonic.net> <11c61fce4243b1dcbea64f85939e9087@sonic.net> Message-ID: <2910c37a1e551c5eb5b6f91a5d5c2ac6@sonic.net> On 2015-10-14 11:29, Danny Yoo wrote: >>>> ###################### >>>> def make_ask(f, l, p): >>>> d = {'Enter your first name: ' : f, >>>> 'Enter your last name: ' : l, >>>> 'Your mobile phone #: ' : p} >>>> return d.get >>>> ###################### >> >> >> This is an example of a 'closure' is it not? > > > Yes, though I try not to use the word "closure" because it's a > technical distinction that isn't really that useful for beginners > because it focuses on the implementation details. That is, when we > say the word "closure", we're emphasizing the fact that it's a > combination of code and the data that it needs to resolve the code's > free variables. And for this discussion, all I really cared about was > that we needed something that knows how to be "called". Anything that > distracts from that point is something I'm actively trying to avoid, > at least at first. > > > We could try to make the code look clever by doing something like: > > ################################################ > make_ask = lambda f, l, p: (lambda key: {'Enter your first name: ' : > f, 'Enter your last name: ' : l, 'Your mobile phone #: ' : p}[key]) > ################################################ > > But this would be death to the point I was trying to make. :P Thank you for 'making the point' and explaining it so well! ak From __peter__ at web.de Wed Oct 14 21:27:37 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 14 Oct 2015 21:27:37 +0200 Subject: [Tutor] how to unittest cli input References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> <0a2179407277fcd3e1580ae5acf131cf@sonic.net> <11c61fce4243b1dcbea64f85939e9087@sonic.net> Message-ID: Alex Kleider wrote: > On 2015-10-13 14:44, Alex Kleider wrote: >> On 2015-10-13 12:11, Danny Yoo wrote: >> >> >>> ###################### >>> def make_ask(f, l, p): >>> d = {'Enter your first name: ' : f, >>> 'Enter your last name: ' : l, >>> 'Your mobile phone #: ' : p} >>> return d.get >>> ###################### > > This is an example of a 'closure' is it not? It does not make big difference, but I would call the return value "bound method" rather than "closure". For me closure implies access to the local namespace of the enclosing function, e. g. def make_ask(f, l, p): d = {'Enter your first name: ' : f, 'Enter your last name: ' : l, 'Your mobile phone #: ' : p} def get(key): return d.get(key) return get Here d is looked up when get() is invoked. Let's make a modification to demonstrate that the current binding of d is used: >>> def make_ask(f, l, p): ... d = {'Enter your first name: ' : f, ... 'Enter your last name: ' : l, ... 'Your mobile phone #: ' : p} ... def get(key): ... return d.get(key) ... def set_d(new_d): ... nonlocal d ... d = new_d ... return get, set_d ... >>> get, set_d = make_ask(*"abc") >>> get("Enter your first name: ") 'a' >>> class WontTell: ... def get(self, key): return "won't tell" ... >>> set_d(WontTell()) >>> get("Enter your first name: ") "won't tell" From niihung at gmail.com Wed Oct 14 22:47:02 2015 From: niihung at gmail.com (=?UTF-8?B?4Kio4Ki/4Ki54Kmw4KiXIOCoquCpsOConOCovuCorOCpgA==?=) Date: Wed, 14 Oct 2015 13:47:02 -0700 Subject: [Tutor] Bitwise & Message-ID: 'if (n & 1)' below works but I don't understand why/how. Kindly help. ============== >>> def fn(n): ... if (n & 1): ... print "n is odd" ... else: ... print "n is even" ... >>> fn(5) n is odd >>> fn(4) n is even =============== Thanks Ni From ben+python at benfinney.id.au Thu Oct 15 01:29:20 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 15 Oct 2015 10:29:20 +1100 Subject: [Tutor] Bitwise & References: Message-ID: <85y4f5rpv3.fsf@benfinney.id.au> ????? ?????? writes: > 'if (n & 1)' below works but I don't understand why/how. Kindly > help. Can you kindly help us understand your confusion? You chose a subject field that indicates why it works, so I don't know what your specific confusion is. -- \ ?Telling pious lies to trusting children is a form of abuse, | `\ plain and simple.? ?Daniel Dennett, 2010-01-12 | _o__) | Ben Finney From joel.goldstick at gmail.com Thu Oct 15 01:29:47 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Wed, 14 Oct 2015 19:29:47 -0400 Subject: [Tutor] Bitwise & In-Reply-To: References: Message-ID: On Wed, Oct 14, 2015 at 4:47 PM, ????? ?????? wrote: > 'if (n & 1)' below works but I don't understand why/how. Kindly help. > > ============== > >>> def fn(n): > ... if (n & 1): > ... print "n is odd" > ... else: > ... print "n is even" > ... > >>> fn(5) > n is odd > >>> fn(4) > n is even > > =============== > & is a bitwise operator, so any odd number and 1 will be one (true), and any even number will be zero (false) Any > > Thanks > Ni > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com/stats/birthdays From alan.gauld at btinternet.com Thu Oct 15 01:35:36 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 15 Oct 2015 00:35:36 +0100 Subject: [Tutor] Bitwise & In-Reply-To: References: Message-ID: On 14/10/15 21:47, ????? ?????? wrote: > 'if (n & 1)' below works but I don't understand why/how. Kindly help. Do you understand what bitwise & does? It takers the logical AND of each bit in the two operands. So, keeping it simple with 2 digit numbers we get 0 = 00 1 = 01 2 = 10 3 = 11 Notice that the second bit in each odd number is a 1. So anding two odd numbers results in the last two bits both being 1 and (1 AND 1) is always 1. So long as any bit is 1 the overall result of (X & Y) will be True, only all zero will be False. So you are guaranteed that two odd numbers ANDed together will be True > > ============== >>>> def fn(n): > ... if (n & 1): > ... print "n is odd" > ... else: > ... print "n is even" So this will indeed work. However its not necessarily good style since it is not obvious how it works unless you understand bitwise operations so arguably, def f(n): if n%2 == 0 : print 'n is even else... Would be clearer. Although that's just a tad subjective. -- 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 nanney.56 at gmail.com Thu Oct 15 01:37:35 2015 From: nanney.56 at gmail.com (Robert Nanney) Date: Wed, 14 Oct 2015 18:37:35 -0500 Subject: [Tutor] Bitwise & In-Reply-To: References: Message-ID: To elaborate a little more this is comparing the 'one' bit. Any odd number will have the 'one' bit set. On Oct 14, 2015 6:30 PM, "Joel Goldstick" wrote: > On Wed, Oct 14, 2015 at 4:47 PM, ????? ?????? wrote: > > > 'if (n & 1)' below works but I don't understand why/how. Kindly help. > > > > ============== > > >>> def fn(n): > > ... if (n & 1): > > ... print "n is odd" > > ... else: > > ... print "n is even" > > ... > > >>> fn(5) > > n is odd > > >>> fn(4) > > n is even > > > > =============== > > > > & is a bitwise operator, so any odd number and 1 will be one (true), and > any even number will be zero (false) > Any > > > > > Thanks > > Ni > > _______________________________________________ > > Tutor maillist - Tutor at python.org > > To unsubscribe or change subscription options: > > https://mail.python.org/mailman/listinfo/tutor > > > > > > -- > Joel Goldstick > http://joelgoldstick.com/stats/birthdays > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From lac at openend.se Thu Oct 15 01:39:29 2015 From: lac at openend.se (Laura Creighton) Date: Thu, 15 Oct 2015 01:39:29 +0200 Subject: [Tutor] Bitwise & In-Reply-To: References: Message-ID: <201510142339.t9ENdTme016221@fido.openend.se> In a message of Wed, 14 Oct 2015 19:29:47 -0400, Joel Goldstick writes: >& is a bitwise operator, so any odd number and 1 will be one (true), and >any even number will be zero (false) You and Ben seem to have missed the problem in the answer. I think that Ni needs to understand _how bitwise operators work_ And it is 1:38 here in the morning, I must get to bed. Somebody else explain it! (and if they don't, Ni, I will get to it tomorrow.) Laura From joel.goldstick at gmail.com Thu Oct 15 02:08:17 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Wed, 14 Oct 2015 20:08:17 -0400 Subject: [Tutor] Bitwise & In-Reply-To: <201510142339.t9ENdTme016221@fido.openend.se> References: <201510142339.t9ENdTme016221@fido.openend.se> Message-ID: On Wed, Oct 14, 2015 at 7:39 PM, Laura Creighton wrote: > In a message of Wed, 14 Oct 2015 19:29:47 -0400, Joel Goldstick writes: > >& is a bitwise operator, so any odd number and 1 will be one (true), and > >any even number will be zero (false) > > You and Ben seem to have missed the problem in the answer. > I think that Ni needs to understand _how bitwise operators work_ > > And it is 1:38 here in the morning, I must get to bed. Somebody > else explain it! (and if they don't, Ni, I will get to it tomorrow.) > > Laura > > Ok the integers can be represented in binary like: 5 = 0101, 0 = 0000, 2 == 0010, etc. When you perform the & operation, it does a bitwise and operation. 0101 & 0001 = 1, 0010 & 0001 = 0. Hope that helps -- Joel Goldstick http://joelgoldstick.com/stats/birthdays From steve at pearwood.info Thu Oct 15 02:26:31 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 15 Oct 2015 11:26:31 +1100 Subject: [Tutor] Bitwise & In-Reply-To: References: Message-ID: <20151015002631.GL13813@ando.pearwood.info> On Wed, Oct 14, 2015 at 01:47:02PM -0700, ????? ?????? wrote: > 'if (n & 1)' below works but I don't understand why/how. Kindly help. > > ============== > >>> def fn(n): > ... if (n & 1): > ... print "n is odd" > ... else: > ... print "n is even" & is the "bitwise AND" operator. It takes each pair of bits (one from each of the two arguments) and combines them like this: 0 & 0 --> 0 0 & 1 --> 0 1 & 0 --> 0 1 & 1 --> 1 So if we take two numbers, say 25 and 43, and look at them in base 2 (binary): 25 --> 011001 in binary 43 --> 101011 in binary the & operator constructs a new binary number from each pair of bits. Starting from the left: 0 & 1 --> 0 1 & 0 --> 0 1 & 1 --> 1 0 & 0 --> 0 0 & 1 --> 0 1 & 1 --> 1 so the result of 25 & 43 is binary 001001 which equals 9 in decimal: py> 25 & 43 9 Your function fn tests for odd numbers by using the bitwise AND of the number with 1. The binary (base 2) version of decimal 1 is 00000001 (fill in as many leading zeroes as you need), so the result of n&1 will be 1 if the binary version of n ends with a 1 bit, otherwise 0. So fn could be written like this (except it will probably be slower): def fn(n): if bin(n).endswith("1"): print "n is odd" else: print "n is even" Why does ending with a 1 bit mean that the number is odd? Here is a reminder about *decimal* numbers: 7453 in decimal means: 7 thousands (7 * 10**3) 4 hundreds (4 * 10**2) 5 tens (5 * 10**1) 3 units (3 * 10**0) The binary number 111001 means: 1 * 2**5 = 32 1 * 2**4 = 16 1 * 2**3 = 8 0 * 2**2 = 0 0 * 2**1 = 0 1 * 2**0 = 1 Adding them together gives (32+16+8+1) = 57. Let's check if this is right: py> int("111001", 2) 57 But the important thing to notice is that, in binary, every bit represents an *even* number, a power of 2: 2, 4, 8, 16, 32, 64, ... EXCEPT the first bit (the one on the far right) which represents the number of units. So if the far-right bit is 0, the number is an even number, and if the far-right bit is 1, the number is odd. By the way, there is also a "bitwise OR" operator that uses this truth-table: 0 | 0 --> 0 0 | 1 --> 1 1 | 0 --> 1 1 | 1 --> 1 and a "bitwise XOR" (exclusive-or) operator: 0 ^ 0 --> 0 0 ^ 1 --> 1 1 ^ 0 --> 1 1 ^ 1 --> 0 -- Steve From akleider at sonic.net Thu Oct 15 06:56:35 2015 From: akleider at sonic.net (Alex Kleider) Date: Wed, 14 Oct 2015 21:56:35 -0700 Subject: [Tutor] how to unittest cli input In-Reply-To: References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> <0a2179407277fcd3e1580ae5acf131cf@sonic.net> <11c61fce4243b1dcbea64f85939e9087@sonic.net> Message-ID: <4e1e77954975c4804f864bc28b402fca@sonic.net> On 2015-10-14 12:27, Peter Otten wrote: > Alex Kleider wrote: > >> On 2015-10-13 14:44, Alex Kleider wrote: >>> On 2015-10-13 12:11, Danny Yoo wrote: >>> >>> >>>> ###################### >>>> def make_ask(f, l, p): >>>> d = {'Enter your first name: ' : f, >>>> 'Enter your last name: ' : l, >>>> 'Your mobile phone #: ' : p} >>>> return d.get >>>> ###################### >> >> This is an example of a 'closure' is it not? > > It does not make big difference, but I would call the return value > "bound > method" rather than "closure". For me closure implies access to the > local > namespace of the enclosing function, e. g. > > def make_ask(f, l, p): > d = {'Enter your first name: ' : f, > 'Enter your last name: ' : l, > 'Your mobile phone #: ' : p} > def get(key): > return d.get(key) > return get > > Here d is looked up when get() is invoked. Let's make a modification to > demonstrate that the current binding of d is used: > >>>> def make_ask(f, l, p): > ... d = {'Enter your first name: ' : f, > ... 'Enter your last name: ' : l, > ... 'Your mobile phone #: ' : p} > ... def get(key): > ... return d.get(key) > ... def set_d(new_d): > ... nonlocal d > ... d = new_d > ... return get, set_d > ... >>>> get, set_d = make_ask(*"abc") >>>> get("Enter your first name: ") > 'a' >>>> class WontTell: > ... def get(self, key): return "won't tell" > ... >>>> set_d(WontTell()) >>>> get("Enter your first name: ") > "won't tell" Thank you, Peter, for your continued efforts to explain. It is all getting pretty convoluted for my poor brain! It took a very long time for me to figure out what the class WontTell was all about. I probably should follow Danny Yoo's advice and not concern myself with this but my curiosity is roused. ak From __peter__ at web.de Thu Oct 15 09:52:31 2015 From: __peter__ at web.de (Peter Otten) Date: Thu, 15 Oct 2015 09:52:31 +0200 Subject: [Tutor] how to unittest cli input References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> <0a2179407277fcd3e1580ae5acf131cf@sonic.net> <11c61fce4243b1dcbea64f85939e9087@sonic.net> <4e1e77954975c4804f864bc28b402fca@sonic.net> Message-ID: Alex Kleider wrote: > On 2015-10-14 12:27, Peter Otten wrote: >> Alex Kleider wrote: >> >>> On 2015-10-13 14:44, Alex Kleider wrote: >>>> On 2015-10-13 12:11, Danny Yoo wrote: >>>> >>>> >>>>> ###################### >>>>> def make_ask(f, l, p): >>>>> d = {'Enter your first name: ' : f, >>>>> 'Enter your last name: ' : l, >>>>> 'Your mobile phone #: ' : p} >>>>> return d.get >>>>> ###################### >>> >>> This is an example of a 'closure' is it not? >> >> It does not make big difference, but I would call the return value >> "bound >> method" rather than "closure". For me closure implies access to the >> local >> namespace of the enclosing function, e. g. >> >> def make_ask(f, l, p): >> d = {'Enter your first name: ' : f, >> 'Enter your last name: ' : l, >> 'Your mobile phone #: ' : p} >> def get(key): >> return d.get(key) >> return get >> >> Here d is looked up when get() is invoked. Let's make a modification to >> demonstrate that the current binding of d is used: >> >>>>> def make_ask(f, l, p): >> ... d = {'Enter your first name: ' : f, >> ... 'Enter your last name: ' : l, >> ... 'Your mobile phone #: ' : p} >> ... def get(key): >> ... return d.get(key) >> ... def set_d(new_d): >> ... nonlocal d >> ... d = new_d >> ... return get, set_d >> ... >>>>> get, set_d = make_ask(*"abc") >>>>> get("Enter your first name: ") >> 'a' >>>>> class WontTell: >> ... def get(self, key): return "won't tell" >> ... >>>>> set_d(WontTell()) >>>>> get("Enter your first name: ") >> "won't tell" > > Thank you, Peter, for your continued efforts to explain. > It is all getting pretty convoluted for my poor brain! > It took a very long time for me to figure out what the > class WontTell was all about. Sorry about that digression. The example would work with any old dict >>> get, set_d = make_ask("John", "Doe", "123") >>> get("Enter your last name: ") 'Doe' >>> set_d({"foo": "bar"}) >>> get("Enter your last name: ") is None True >>> get("foo") 'bar' but that way the effect of rebinding d (which is what happens) is the same as replacing the data in the dict initially bound to d. > I probably should follow Danny Yoo's advice and not concern > myself with this but my curiosity is roused. From reuben.dlink at gmail.com Thu Oct 15 18:00:09 2015 From: reuben.dlink at gmail.com (Reuben) Date: Thu, 15 Oct 2015 21:30:09 +0530 Subject: [Tutor] File operation query Message-ID: Hi All, I need some clarification for below code. In line 2 of below code snippet, I have provided read and write permission. Assuming I have provided some string input as requested in line 1 - when I try to open "check.txt" file after running the script, it is always empty - it does not display the user input provided. May I know why? ###################################################################### input1 = raw_input("Input1:") file = open("check.txt", "r+") file.write(input1 + "\n") for line in file: print line print file.close() ###################################################################### Regards, RD. From __peter__ at web.de Thu Oct 15 18:30:46 2015 From: __peter__ at web.de (Peter Otten) Date: Thu, 15 Oct 2015 18:30:46 +0200 Subject: [Tutor] File operation query References: Message-ID: Reuben wrote: > I need some clarification for below code. In line 2 of below code snippet, > I have provided read and write permission. Assuming I have provided some > string input as requested in line 1 - when I try to open "check.txt" file > after running the script, it is always empty - it does not display the > user input provided. > > May I know why? I don't know the details, but the problem is the caching mechanism used to speed up file iteration. > input1 = raw_input("Input1:") > file = open("check.txt", "r+") > file.write(input1 + "\n") > for line in file: > print line > print file.close() I use the rule of thumb that file iteration and other methods are incompatible in Python 2. You may be able to make it work (in this case a file.flush() before the for loop seems to do the job), but I prefer not to bother. From joel.goldstick at gmail.com Thu Oct 15 18:32:02 2015 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Thu, 15 Oct 2015 12:32:02 -0400 Subject: [Tutor] File operation query In-Reply-To: References: Message-ID: On Thu, Oct 15, 2015 at 12:00 PM, Reuben wrote: > Hi All, > > I need some clarification for below code. In line 2 of below code snippet, > I have provided read and write permission. Assuming I have provided some > string input as requested in line 1 - when I try to open "check.txt" file > after running the script, it is always empty - it does not display the user > input provided. > > May I know why? > > ###################################################################### > > input1 = raw_input("Input1:") > > > file = open("check.txt", "r+") > > file.write(input1 + "\n") > > > for line in file: > print line > > > print file.close() > the above line should probably be: > file.close() Do you have a traceback? Can you add that to your question? > ###################################################################### > > > Regards, > RD. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Joel Goldstick http://joelgoldstick.com/stats/birthdays From emile at fenx.com Thu Oct 15 18:47:40 2015 From: emile at fenx.com (Emile van Sebille) Date: Thu, 15 Oct 2015 09:47:40 -0700 Subject: [Tutor] File operation query In-Reply-To: References: Message-ID: On 10/15/2015 9:00 AM, Reuben wrote: > Hi All, > > I need some clarification for below code. In line 2 of below code snippet, > I have provided read and write permission. Assuming I have provided some > string input as requested in line 1 - when I try to open "check.txt" file > after running the script, it is always empty - it does not display the user > input provided. > > May I know why? > > ###################################################################### > > input1 = raw_input("Input1:") > > > file = open("check.txt", "r+") > > file.write(input1 + "\n") > try inserting file.flush() here Emile > > for line in file: > print line > > > print file.close() > > ###################################################################### > > > Regards, > RD. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From emile at fenx.com Thu Oct 15 18:49:28 2015 From: emile at fenx.com (Emile van Sebille) Date: Thu, 15 Oct 2015 09:49:28 -0700 Subject: [Tutor] File operation query In-Reply-To: References: Message-ID: On 10/15/2015 9:00 AM, Reuben wrote: > Hi All, > > I need some clarification for below code. In line 2 of below code snippet, > I have provided read and write permission. Assuming I have provided some > string input as requested in line 1 - when I try to open "check.txt" file > after running the script, it is always empty - it does not display the user > input provided. > > May I know why? > > ###################################################################### > > input1 = raw_input("Input1:") > > > file = open("check.txt", "r+") > > file.write(input1 + "\n") > > Also, the line below continues from the last insertion -- you'll also need to reposition the file pointer or re-open the file. Emile > for line in file: > print line > > > print file.close() > > ###################################################################### > > > Regards, > RD. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From alan.gauld at btinternet.com Thu Oct 15 19:35:12 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 15 Oct 2015 18:35:12 +0100 Subject: [Tutor] File operation query In-Reply-To: References: Message-ID: On 15/10/15 17:00, Reuben wrote: > I need some clarification for below code. In line 2 of below code snippet, > I have provided read and write permission. Thios is nearly always a bad idea and leads to all sorts of complications, as you are discovering! > string input as requested in line 1 - when I try to open "check.txt" file > after running the script, it is always empty - it does not display the user > input provided. Its not empty but you are positioned after the text you inserted. > > input1 = raw_input("Input1:") > file = open("check.txt", "r+") > > file.write(input1 + "\n") This writes your text at the start of the file (incidentally overwriting anything that was there from the previous run). It leaves the file cursor at the end of your txt. > for line in file: > print line This tries to read from the file cursor to the end of the file. But you are already at the end so it returns nothing. You need to do a seek(0) to put the cursor back to the start. Then remember to go back to the end before trying to write again. I told you it was more complicated! > print file.close() printing close() is not useful. 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 akleider at sonic.net Thu Oct 15 23:22:39 2015 From: akleider at sonic.net (Alex Kleider) Date: Thu, 15 Oct 2015 14:22:39 -0700 Subject: [Tutor] how to unittest cli input In-Reply-To: References: <9c3075c0e0d290b62fb614da8f406d55@sonic.net> <0a2179407277fcd3e1580ae5acf131cf@sonic.net> <11c61fce4243b1dcbea64f85939e9087@sonic.net> Message-ID: On 2015-10-14 11:29, Danny Yoo wrote: >>>> ###################### >>>> def make_ask(f, l, p): >>>> d = {'Enter your first name: ' : f, >>>> 'Enter your last name: ' : l, >>>> 'Your mobile phone #: ' : p} >>>> return d.get >>>> ###################### >> >> >> This is an example of a 'closure' is it not? > > > Yes, though I try not to use the word "closure" because it's a > technical distinction that isn't really that useful for beginners > because it focuses on the implementation details. That is, when we > say the word "closure", we're emphasizing the fact that it's a > combination of code and the data that it needs to resolve the code's > free variables. I've been pondering the above and am wondering why the use of "...and the data that it needs to resolve the code's free variables." rather than simply "...and the data needed by the code to do its job." I think what I'm asking is what exactly is meant by 'free variables' or put another way, what makes a variable 'free' or otherwise? ak From alan.gauld at btinternet.com Fri Oct 16 01:26:28 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 16 Oct 2015 00:26:28 +0100 Subject: [Tutor] Changes to dbm module/file format Message-ID: Has anyone noticed a change to the DBM file format or is it an OS specific thing? Last time I used dbm it was on a Windoze box with Python 3.3 and it generated sets of 3 files for each 'database' created. (I think this is what it did under v2 as well?) I just used it on my Linux box in 3.4 and its only creating a single file. Is this a 3.4 change or a Linux/dbm feature? I can't use Python on Windows at the moment so I can't check. Does anyone know? I don't see anything in the module docs about file formats differing by OS... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From steve at pearwood.info Fri Oct 16 02:21:10 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Fri, 16 Oct 2015 11:21:10 +1100 Subject: [Tutor] Changes to dbm module/file format In-Reply-To: References: Message-ID: <20151016002110.GB11980@ando.pearwood.info> On Fri, Oct 16, 2015 at 12:26:28AM +0100, Alan Gauld wrote: > Has anyone noticed a change to the DBM file format or is it an OS > specific thing? Last time I used dbm it was on a Windoze box with > Python 3.3 and it generated sets of 3 files for each 'database' > created. (I think this is what it did under v2 as well?) Python 2.5, under Linux: dbm.open('foo', 'w') creates two files: foo.dir foo.pag Likewise for Python 2.7. In Python 3.3 and 3.4, you need to pass the 'c' or 'n' flag, not 'w', and only a single file is created: "foo". -- Steve From linuxfrosch at gmail.com Thu Oct 15 19:32:54 2015 From: linuxfrosch at gmail.com (Martin A. Brown) Date: Thu, 15 Oct 2015 10:32:54 -0700 Subject: [Tutor] File operation query In-Reply-To: References: Message-ID: Hello and good day Reuben, >> I need some clarification for below code. In line 2 of below code >> snippet, I have provided read and write permission. Assuming I >> have provided some string input as requested in line 1 - when I >> try to open "check.txt" file after running the script, it is >> always empty - it does not display the user input provided. >> >> May I know why? > > I don't know the details, but the problem is the caching mechanism > used to speed up file iteration. I find Peter's comment interesting. I did not know this. >> input1 = raw_input("Input1:") >> file = open("check.txt", "r+") >> file.write(input1 + "\n") >> for line in file: >> print line >> print file.close() > > I use the rule of thumb that file iteration and other methods are > incompatible in Python 2. > > You may be able to make it work (in this case a file.flush() > before the for loop seems to do the job), but I prefer not to > bother. I would like to make two additional comments: Unless you are operating on many (many) files, then, why not call close() on the file and reopen. Until performance concerns dominate (possibly, never), this should offer you the predictability you expect, without worrying about file pointer location. If you are using Python 2, then don't call your variable 'file'. The word 'file' in Python 2 behaves like open file("check.txt", "r+") # means the same thing as: open("check.txt", "r+") I would, therefore write your program like this: input1 = raw_input("Input1:") f = open("check.txt", "w") f.write(input1 + "\n") f.close() f = open("check.txt", "r") for line in f: print line f.close() Good luck! -Martin [0] https://docs.python.org/2/library/functions.html#file -- Martin A. Brown http://linux-ip.net/ From alan.gauld at btinternet.com Fri Oct 16 09:38:25 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 16 Oct 2015 08:38:25 +0100 Subject: [Tutor] Changes to dbm module/file format In-Reply-To: <20151016002110.GB11980@ando.pearwood.info> References: <20151016002110.GB11980@ando.pearwood.info> Message-ID: On 16/10/15 01:21, Steven D'Aprano wrote: > Python 2.5, under Linux: > > dbm.open('foo', 'w') > > creates two files: > > foo.dir foo.pag > > > Likewise for Python 2.7. > Thanks Steven. > In Python 3.3 and 3.4, you need to pass the 'c' or 'n' flag, not 'w', > and only a single file is created: "foo". I always used 'c' to create a new 'file' even on 2.x... Can anyone confirm those results on Windows for 3.x please? PS. Although Steven only got 2 files under 2.7 a third(.bak) would be created if he modified the contents. Hence my comment about 3 files being produced per database. -- 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 reuben.dlink at gmail.com Fri Oct 16 09:52:59 2015 From: reuben.dlink at gmail.com (Reuben) Date: Fri, 16 Oct 2015 13:22:59 +0530 Subject: [Tutor] File operation query In-Reply-To: References: Message-ID: Thanks everyone for the suggestion. At the moment, file.flush() resolves the problem - but I will also give a thought to suggestions provided by other members in this email chain. Regards, RD On Thu, Oct 15, 2015 at 11:05 PM, Alan Gauld wrote: > On 15/10/15 17:00, Reuben wrote: > > I need some clarification for below code. In line 2 of below code snippet, >> I have provided read and write permission. >> > > Thios is nearly always a bad idea and leads to all sorts of complications, > as you are discovering! > > string input as requested in line 1 - when I try to open "check.txt" file >> after running the script, it is always empty - it does not display the >> user >> input provided. >> > > Its not empty but you are positioned after the text you inserted. > > >> input1 = raw_input("Input1:") >> file = open("check.txt", "r+") >> >> file.write(input1 + "\n") >> > > This writes your text at the start of the file > (incidentally overwriting anything that was there > from the previous run). It leaves the file cursor > at the end of your txt. > > for line in file: >> print line >> > > This tries to read from the file cursor to the end of the file. > But you are already at the end so it returns nothing. > You need to do a seek(0) to put the cursor back to the start. > Then remember to go back to the end before trying to write again. > I told you it was more complicated! > > print file.close() >> > > printing close() is not useful. > > HTH > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From __peter__ at web.de Fri Oct 16 12:50:29 2015 From: __peter__ at web.de (Peter Otten) Date: Fri, 16 Oct 2015 12:50:29 +0200 Subject: [Tutor] Changes to dbm module/file format References: Message-ID: Alan Gauld wrote: > Has anyone noticed a change to the DBM file format or is it an OS > specific thing? Last time I used dbm it was on a Windoze box with > Python 3.3 and it generated sets of 3 files for each 'database' > created. (I think this is what it did under v2 as well?) > > I just used it on my Linux box in 3.4 and its only creating > a single file. Is this a 3.4 change or a Linux/dbm feature? > > I can't use Python on Windows at the moment so I can't check. > Does anyone know? I don't see anything in the module docs > about file formats differing by OS... dbm in Python 3 or anydbm in Python 2 have logic to find the best available key-value store. On Windows you are more likely to end up with the last resort dbm.dumb (dumbdbm in py2) which uses three files (.dat, .dir, and .bak) but I don't think that's always the case. From northgoingzak at gmail.com Sat Oct 17 00:31:22 2015 From: northgoingzak at gmail.com (zak nelson) Date: Fri, 16 Oct 2015 17:31:22 -0500 Subject: [Tutor] I don't understand why this program is said to be "not defined" when I test it. Message-ID: I don't understand why this program is said to be "not defined" when I test it. def problem22(aList): length=len(aList) if (length>6): bueler=False else: bueler=True for i in aList: if(i < 0 and i > 6)==False: bueler=False else: buler=True if type(i)!=("integer"): bueler=False else: bueler=True return bueler From alan.gauld at btinternet.com Sat Oct 17 01:16:57 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sat, 17 Oct 2015 00:16:57 +0100 Subject: [Tutor] I don't understand why this program is said to be "not defined" when I test it. In-Reply-To: References: Message-ID: On 16/10/15 23:31, zak nelson wrote: > I don't understand why this program is said to be "not defined" when I test > it. In future please be more precise in describing the problem, and that means including the full error message in the post. It contains a lot of useful information. I'm guessing it doesn't say that the program is not defined but it says the name buler is not defined? Is that correct? Notice the spelling? Now look at your code > def problem22(aList): > length=len(aList) > if (length>6): > bueler=False > else: > bueler=True > for i in aList: > if(i < 0 and i > 6)==False: > bueler=False > else: > buler=True > if type(i)!=("integer"): > bueler=False > else: > bueler=True > return bueler But there are a couple of other issues in there too. Specifically this line: if(i < 0 and i > 6)==False: The bit in parentheses can never be true because i can never be both <0 and >6 at the same time. So the if statement is always true and the next line is always executed. Also the line if type(i)!=("integer"): Will never be true because the string 'integer' is not a type. You should use the type name: if type(i) != int or compare to the type of a known value: if type(i) != type(5): In the case of an int the first one would be better. A final refinement is that for these kinds of comparisons it probably reads better to use is/is not rather than the ==/!= symbols, so: if type(i) is not int: 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 Sat Oct 17 14:26:23 2015 From: bgailer at gmail.com (Bob Gailer) Date: Sat, 17 Oct 2015 08:26:23 -0400 Subject: [Tutor] I don't understand why this program is said to be "not defined" when I test it. In-Reply-To: References: Message-ID: Also: Briefly describe problem 22 Show us what you did to test the program It would be better to test for integer before doing a numeric comparison There is no need ever to compare a boolean expression to true or false. All you need is either if condition or if not condition. A good short cut for a range test is if 0<= x <= 6: It is not necessary to surround a condition with parentheses. Your code will be simpler if you initially set Bueller to true, then change it to false as needed. Please excuse my spelling as I am dictating this. Who would have thought so many comments could come from such a simple piece of code. On Oct 16, 2015 7:17 PM, "Alan Gauld" wrote: > On 16/10/15 23:31, zak nelson wrote: > >> I don't understand why this program is said to be "not defined" when I >> test >> it. >> > > In future please be more precise in describing the problem, > and that means including the full error message in the post. > It contains a lot of useful information. > > I'm guessing it doesn't say that the program is not defined > but it says the name buler is not defined? Is that correct? > > Notice the spelling? > Now look at your code > > def problem22(aList): >> length=len(aList) >> if (length>6): >> bueler=False >> else: >> bueler=True >> for i in aList: >> if(i < 0 and i > 6)==False: >> bueler=False >> else: >> buler=True >> if type(i)!=("integer"): >> bueler=False >> else: >> bueler=True >> return bueler >> > > But there are a couple of other issues in there too. > Specifically this line: > > if(i < 0 and i > 6)==False: > > The bit in parentheses can never be true because i can > never be both <0 and >6 at the same time. So the if > statement is always true and the next line is always > executed. > > Also the line > > if type(i)!=("integer"): > > Will never be true because the string 'integer' is not a type. > You should use the type name: > > if type(i) != int > > or compare to the type of a known value: > > if type(i) != type(5): > > In the case of an int the first one would be better. > A final refinement is that for these kinds of comparisons > it probably reads better to use is/is not rather > than the ==/!= symbols, so: > > if type(i) is not int: > > HTH > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From jjhartley at gmail.com Sun Oct 18 03:20:14 2015 From: jjhartley at gmail.com (James Hartley) Date: Sat, 17 Oct 2015 20:20:14 -0500 Subject: [Tutor] accessing modules found throughout a package? Message-ID: In my current project, I am developing a package. It makes sense to embed tests throughout the package's directory structure as they should be part of the package & its distribution. It may raise eyebrows that I have tests sprinkled through various directories, but there are reasons for keeping some tests in the same proximity as the modules needed to import data into a database. There are several directories importing data according to different constraints. The problem/annoyance I am facing is that tests need to access modules in other directories, I have to play games at the beginning of each test file which looks at os.path.realpath(__file__) to ascertain where the root of the package can be found before calling os.path.append(). Since the package is still under development, its structure is still in flux. As a result, any structural change requires that I re-adjust each test file ensuring that the paths are still correct. Here is the package's general structure: +/package_directory/ | +/data/ + base_classes_used_by_some_tests.py | +/import_1/ | + test_code_requiring_base_classes_above.py | +/import_2/ | + different_test_code_requiring_base_classes_above.py | +/tests/ | + more_test_code_requiring_base_classes_above.py What is a better solution to minimize any tweaking forced upon the test code? It seems that formally installing the package will only remedy some of the problems I am currently experiencing. Any suggestions you may have will be very welcomed. Jim From ben+python at benfinney.id.au Sun Oct 18 03:29:58 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Sun, 18 Oct 2015 12:29:58 +1100 Subject: [Tutor] accessing modules found throughout a package? References: Message-ID: <85vba5q7zd.fsf@benfinney.id.au> James Hartley writes: > In my current project, I am developing a package. It makes sense to > embed tests throughout the package's directory structure as they > should be part of the package & its distribution. Yet, as you're finding, it also causes headaches. First, know that you don't need to scatter the test suite through out the rest of your code in order to meet the goal of including it in the distribution. You can distribute the test suite along with the rest, by specifying it as part of the source distribution. See the ?manifest? for Distutils. To have your test suite run correctly when it's located separately from the system under test, you need to specify the top-level directory as being in the Python import path, during the test suite run. Then, you can have all the test suite modules do relative imports from that top level, to get the modules they need to import from the system under test. That way, the test suite imports modules the same way any other user of your code will import them: from the top level package. Look up ?relative and absolute imports? to see how they work, and how they differ, in Python. > Any suggestions you may have will be very welcomed. I hope that helps. -- \ ?Faith is generally nothing more than the permission religious | `\ people give to one another to believe things strongly without | _o__) evidence.? ?Sam Harris, _Letter to a Christian Nation_ 2006 | Ben Finney From steve at pearwood.info Sun Oct 18 04:49:46 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Sun, 18 Oct 2015 13:49:46 +1100 Subject: [Tutor] accessing modules found throughout a package? In-Reply-To: References: Message-ID: <20151018024946.GC3725@ando.pearwood.info> On Sat, Oct 17, 2015 at 08:20:14PM -0500, James Hartley wrote: > In my current project, I am developing a package. It makes sense to embed > tests throughout the package's directory structure as they should be part > of the package & its distribution. It may raise eyebrows that I have tests > sprinkled through various directories, but there are reasons for keeping > some tests in the same proximity as the modules needed to import data into > a database. There are several directories importing data according to > different constraints. I'm sure that there are "reasons", but are they good reasons? The package structure you show strikes me as odd. You have code under a "data" subdirectory, which seems deeply weird to me. Have you considered a more convention structure? +-- package +-- __init__.py +-- module.py +-- subpackage +-- __init__.py +-- module.py +-- data +-- data.jpg +-- data.txt +-- tests +-- __init__.py +-- base_tests.py +-- more_tests.py +-- other_tests.py which will correspond to Python imports like: # Absolute imports import package import package.module import package.subpackage import package.subpackage.module import package.tests import package.tests.more_tests which will work from your package's callers, and from within the package itself provided the top level directory can be found within Python's path. Within the package you can also use relative imports, see the docs for more detail. So within (say) more_tests.py you should be able to say: from . import base_tests or import package.tests.base_tests You can get the path of the data subdirectory like so: import package path = os.path.join(package.__path__[0], "data") At the very least, this conventional structure will avoid problems with the test modules, since they won't change location. Only your package modules themselves will change location during development. -- Steve From rahulpathakpython at gmail.com Sun Oct 18 07:09:15 2015 From: rahulpathakpython at gmail.com (Rahul Pathak) Date: Sun, 18 Oct 2015 10:39:15 +0530 Subject: [Tutor] GET function not executed Message-ID: Hi, I started with python web module and i have no experience with web. I used the example which is on the web.py site - ---------------------------------- import web urls = { '/', 'index' } class index: def GET(self): return "Hello World" if __name__ == "__main__": app = web.application(urls, globals()) app.run() ----------------------------------------- But when I execute this code on terminal and put http://localhost:8080/ in browser then I get "not found" in browser and at terminal I get error - $ python webse.py http://0.0.0.0:8080/ 127.0.0.1:51204 - - [18/Oct/2015 10:29:46] "HTTP/1.1 GET /" - 404 Not Found 127.0.0.1:51204 - - [18/Oct/2015 10:29:47] "HTTP/1.1 GET /" - 404 Not Found 127.0.0.1:51204 - - [18/Oct/2015 10:29:47] "HTTP/1.1 GET /" - 404 Not Found Looks like GET method is not visible and not getting executed. Please help Regards Rahul From __peter__ at web.de Sun Oct 18 11:14:18 2015 From: __peter__ at web.de (Peter Otten) Date: Sun, 18 Oct 2015 11:14:18 +0200 Subject: [Tutor] GET function not executed References: Message-ID: Rahul Pathak wrote: > Hi, > > I started with python web module and i have no experience with web. > > I used the example which is on the web.py site - > > ---------------------------------- > import web > > urls = { > '/', 'index' > } > > class index: > def GET(self): > return "Hello World" > > if __name__ == "__main__": > app = web.application(urls, globals()) > app.run() > ----------------------------------------- > > But when I execute this code on terminal and put http://localhost:8080/ in > browser then I get "not found" in browser and at terminal I get error - > > $ python webse.py > http://0.0.0.0:8080/ > 127.0.0.1:51204 - - [18/Oct/2015 10:29:46] "HTTP/1.1 GET /" - 404 Not > Found 127.0.0.1:51204 - - [18/Oct/2015 10:29:47] "HTTP/1.1 GET /" - 404 > Not Found 127.0.0.1:51204 - - [18/Oct/2015 10:29:47] "HTTP/1.1 GET /" - > 404 Not Found > > Looks like GET method is not visible and not getting executed. The problem is > urls = { > '/', 'index' > } The use of {...} makes this a set literal, and the order of the items in a set is undefined. To prevent a class of attacks on web applications it may even change between invocations: $ for i in {1..10}; do echo -n "PYTHONHASHSEED=$i --> "; PYTHONHASHSEED=$i python setdemo.py; done PYTHONHASHSEED=1 --> set(['index', '/']) PYTHONHASHSEED=2 --> set(['/', 'index']) PYTHONHASHSEED=3 --> set(['index', '/']) PYTHONHASHSEED=4 --> set(['index', '/']) PYTHONHASHSEED=5 --> set(['/', 'index']) PYTHONHASHSEED=6 --> set(['/', 'index']) PYTHONHASHSEED=7 --> set(['index', '/']) PYTHONHASHSEED=8 --> set(['/', 'index']) PYTHONHASHSEED=9 --> set(['index', '/']) PYTHONHASHSEED=10 --> set(['index', '/']) If you do not set the PYTHONHASHSEED environment variable python picks one at random. For every run of the script where "index" comes first web.py would try to match the url provided by the browser against the regex "^index$" instead of "^/$" and will of course fail. The original code at http://webpy.org/docs/0.3/tutorial uses (...), i. e. a tuple instead of a set. Tuples and lists [...] preserve the order as written, so your script should work once you change urls into a tuple or list. PS: Fortunately (!) the "wrong" order is quite frequent; otherwise you would think that your program worked but would still see occasional hard to reproduce glitches. From __peter__ at web.de Sun Oct 18 11:21:21 2015 From: __peter__ at web.de (Peter Otten) Date: Sun, 18 Oct 2015 11:21:21 +0200 Subject: [Tutor] GET function not executed References: Message-ID: Peter Otten wrote: > The use of {...} makes this a set literal, and the order of the items in a > set is undefined. To prevent a class of attacks on web applications it may > even change between invocations: Sorry, I forgot to include the source of setdemo.py. It contains just one line: print {'/', 'index'} > $ for i in {1..10}; do echo -n "PYTHONHASHSEED=$i --> "; PYTHONHASHSEED=$i > python setdemo.py; done > PYTHONHASHSEED=1 --> set(['index', '/']) > PYTHONHASHSEED=2 --> set(['/', 'index']) > PYTHONHASHSEED=3 --> set(['index', '/']) > PYTHONHASHSEED=4 --> set(['index', '/']) > PYTHONHASHSEED=5 --> set(['/', 'index']) > PYTHONHASHSEED=6 --> set(['/', 'index']) > PYTHONHASHSEED=7 --> set(['index', '/']) > PYTHONHASHSEED=8 --> set(['/', 'index']) > PYTHONHASHSEED=9 --> set(['index', '/']) > PYTHONHASHSEED=10 --> set(['index', '/']) From alan.gauld at btinternet.com Sun Oct 18 16:40:44 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 18 Oct 2015 15:40:44 +0100 Subject: [Tutor] GET function not executed In-Reply-To: References: Message-ID: On 18/10/15 06:09, Rahul Pathak wrote: > Hi, > > I started with python web module and i have no experience with web. OK, web.py is not part of the standard library and I have no experience with that specific framework. I also see Peter Otten has picked up an issue about the urls set. But there's something else that I notice which may be significant... > But when I execute this code on terminal and put http://localhost:8080/ in > browser then I get "not found" in browser and at terminal I get error - > > $ python webse.py > http://0.0.0.0:8080/ > 127.0.0.1:51204 - - [18/Oct/2015 10:29:46] "HTTP/1.1 GET /" - 404 Not Found Note the first line of output uses 0.0.0.0:8080 which may suggest that's what the server is expecting? But you are accessing localhost which is 127.0.0.1. The fact that you even get some kind of error message suggests the server is somehow detecting the localhost request but maybe its looking in the wrong place for the GET result? I don't know the framework and so don't know what the significance of the 0.0.0.0 is but it might be relevant so I thought I'd point it out. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From akleider at sonic.net Sun Oct 18 17:07:07 2015 From: akleider at sonic.net (Alex Kleider) Date: Sun, 18 Oct 2015 08:07:07 -0700 Subject: [Tutor] =?utf-8?q?accessing_modules_found_throughout_a_package=3F?= In-Reply-To: <20151018024946.GC3725@ando.pearwood.info> References: <20151018024946.GC3725@ando.pearwood.info> Message-ID: <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> On 2015-10-17 19:49, Steven D'Aprano wrote: > which will work from your package's callers, and from within the > package > itself provided the top level directory can be found within Python's > path. Within the package you can also use relative imports, see the > docs for more detail. How does one arrange so "the top level directory _can_ be found within Python's path."? From akleider at sonic.net Sun Oct 18 17:33:50 2015 From: akleider at sonic.net (Alex Kleider) Date: Sun, 18 Oct 2015 08:33:50 -0700 Subject: [Tutor] =?utf-8?q?accessing_modules_found_throughout_a_package=3F?= In-Reply-To: <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> Message-ID: <28a18611efef6169e40c3d440673bdb4@sonic.net> On 2015-10-18 08:07, Alex Kleider wrote: > On 2015-10-17 19:49, Steven D'Aprano wrote: > >> which will work from your package's callers, and from within the >> package >> itself provided the top level directory can be found within Python's >> path. Within the package you can also use relative imports, see the >> docs for more detail. > > How does one arrange so "the top level directory _can_ be found within > Python's path."? > Is the answer to include the following at the beginning of each file? if not 'path/to/top/level/package/directory' in sys.path: sys.path.append('path/to/top/level/package/directory') From alan.gauld at btinternet.com Sun Oct 18 19:26:51 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 18 Oct 2015 18:26:51 +0100 Subject: [Tutor] accessing modules found throughout a package? In-Reply-To: <28a18611efef6169e40c3d440673bdb4@sonic.net> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <28a18611efef6169e40c3d440673bdb4@sonic.net> Message-ID: On 18/10/15 16:33, Alex Kleider wrote: >> How does one arrange so "the top level directory _can_ be found within >> Python's path."? > > Is the answer to include the following at the beginning of each file? > > if not 'path/to/top/level/package/directory' in sys.path: > sys.path.append('path/to/top/level/package/directory') You could, but you can also add it to your PYTHONPATH environment variable. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From akleider at sonic.net Sun Oct 18 19:51:34 2015 From: akleider at sonic.net (Alex Kleider) Date: Sun, 18 Oct 2015 10:51:34 -0700 Subject: [Tutor] =?utf-8?q?accessing_modules_found_throughout_a_package=3F?= In-Reply-To: References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <28a18611efef6169e40c3d440673bdb4@sonic.net> Message-ID: <0a08bfa46fbad1c95e1b0b3ad80c39db@sonic.net> On 2015-10-18 10:26, Alan Gauld wrote: > On 18/10/15 16:33, Alex Kleider wrote: > >>> How does one arrange so "the top level directory _can_ be found >>> within >>> Python's path."? >> >> Is the answer to include the following at the beginning of each file? >> >> if not 'path/to/top/level/package/directory' in sys.path: >> sys.path.append('path/to/top/level/package/directory') > > You could, but you can also add it to your PYTHONPATH environment > variable. It seems to not exist: (venv)alex at x301:~/Py/CSV/debk$ echo $PYTHONPATH Should I add the following to the end of my ~/.bashrc file? export PYTHONPATH="$PYTHONPATH:/home/alex/Py" From martin at linux-ip.net Sun Oct 18 20:15:23 2015 From: martin at linux-ip.net (Martin A. Brown) Date: Sun, 18 Oct 2015 11:15:23 -0700 Subject: [Tutor] accessing modules found throughout a package? In-Reply-To: <0a08bfa46fbad1c95e1b0b3ad80c39db@sonic.net> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <28a18611efef6169e40c3d440673bdb4@sonic.net> <0a08bfa46fbad1c95e1b0b3ad80c39db@sonic.net> Message-ID: Hello Alex, >>>> How does one arrange so "the top level directory _can_ be found within >>>> Python's path."? >>> >>> Is the answer to include the following at the beginning of each file? >>> >>> if not 'path/to/top/level/package/directory' in sys.path: >>> sys.path.append('path/to/top/level/package/directory') >> >> You could, but you can also add it to your PYTHONPATH environment variable. > > It seems to not exist: > (venv)alex at x301:~/Py/CSV/debk$ echo $PYTHONPATH > > Should I add the following to the end of my ~/.bashrc file? > export PYTHONPATH="$PYTHONPATH:/home/alex/Py" Quite possibly. You can test it out easily as follows to be certain that this allows you to import your Python easily. $ PYTHONPATH=/home/alex/Py python >>> import something_you_wrote If that works, then, yes. See also the docs [0]. This should certainly be suitable for personal work. It is generally polite to prefix any existing value of PYTHONPATH before adding your own. For a possibly esoteric improvement, you might consider a little shell refinement to avoid leaving any empty path in the variable. What do I mean? After the fragment in your .bashrc (assuming PYTHONPATH remains unset before the above line runs), you will end up with: PYTHONPATH=:/home/alex/Py Oops! There's an empty path in there in the first position. A minor improvement would be to only prepend the PYTHONPATH and required colon if there's a value to PYTHONPATH already. So, this little beautifully obnoxious bash parameter expansion gem will accomplish that for you: PYTHONPATH="${PYTHONPATH:+$PYTHONPATH:}/home/alex/Py" Good luck, -Martin [0] https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH -- Martin A. Brown http://linux-ip.net/ From ben+python at benfinney.id.au Sun Oct 18 20:47:01 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Mon, 19 Oct 2015 05:47:01 +1100 Subject: [Tutor] accessing modules found throughout a package? References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <28a18611efef6169e40c3d440673bdb4@sonic.net> <0a08bfa46fbad1c95e1b0b3ad80c39db@sonic.net> Message-ID: <85pp0cqaje.fsf@benfinney.id.au> Alex Kleider writes: > Should I add the following to the end of my ~/.bashrc file? > export PYTHONPATH="$PYTHONPATH:/home/alex/Py" No, because the entry should only be in PYTHONPATH *if* you want imports to come from that package. So the advice is: * For the run-time application, it should be installed using the Distutils system (?python3 ./setup.py install?) and hence its modules will be available on the path as normal. That is, the normal operation of the code will *not* be to run it from the development working tree, so that path should not be in your normal PYTHONPATH. * THe ?sys.path? sequence is equivalent to the PYTHONPATH environment variable, and can be modified in your test suite's Python code as described elsewhere. But don't do that, because: * Python will automatically add a ?sys.path? entry for the directory containing the script named on the command line. So this: $ cd ~/Projects/lorem/ $ python3 ./setup.py test will run the ?setup.py? program with ?sys.path? already modified to contain the directory ?/home/YOURUSERNAME/Projects/lorem?. Any packages in that directory are available for absolute import, *during* that test suite run. * For this reason (and others), it's recommended to have ?setup.py? at the top level of your working tree. Put all the other Python code in packages and modules importable from the same location as ?setup.py?, and run ?setup.py? from that directory to allow the ?sys.path? modification to work as expected. -- \ ?Alternative explanations are always welcome in science, if | `\ they are better and explain more. Alternative explanations that | _o__) explain nothing are not welcome.? ?Victor J. Stenger, 2001-11-05 | Ben Finney From ben+python at benfinney.id.au Sun Oct 18 20:57:33 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Mon, 19 Oct 2015 05:57:33 +1100 Subject: [Tutor] accessing modules found throughout a package? References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <28a18611efef6169e40c3d440673bdb4@sonic.net> <0a08bfa46fbad1c95e1b0b3ad80c39db@sonic.net> <85pp0cqaje.fsf@benfinney.id.au> Message-ID: <85lhb0qa1u.fsf@benfinney.id.au> Ben Finney writes: > * Python will automatically add a ?sys.path? entry for the directory > containing the script named on the command line. So this: > > $ cd ~/Projects/lorem/ > $ python3 ./setup.py test > > will run the ?setup.py? program with ?sys.path? already modified to > contain the directory ?/home/YOURUSERNAME/Projects/lorem?. Any > packages in that directory are available for absolute import, *during* > that test suite run. This behaviour is detailed further in the documentation . -- \ ?The way to build large Python applications is to componentize | `\ and loosely-couple the hell out of everything.? ?Aahz | _o__) | Ben Finney From steve at pearwood.info Mon Oct 19 03:01:48 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Mon, 19 Oct 2015 12:01:48 +1100 Subject: [Tutor] accessing modules found throughout a package? In-Reply-To: <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> Message-ID: <20151019010147.GA3813@ando.pearwood.info> On Sun, Oct 18, 2015 at 08:07:07AM -0700, Alex Kleider wrote: > On 2015-10-17 19:49, Steven D'Aprano wrote: > > >which will work from your package's callers, and from within the > >package > >itself provided the top level directory can be found within Python's > >path. Within the package you can also use relative imports, see the > >docs for more detail. > > How does one arrange so "the top level directory _can_ be found within > Python's path."? The boring, conventional way is to install the package under site-packages. E.g. if Python is installed here: /usr/local/lib/python2.7/ (for example), there will also be a directory: /usr/local/lib/python2.7/site-packages/ If you stick the package directory inside site-packages, it will be visible to be imported from Python2.7. If you install the package using an installer like pip or setuptools, chances are it will automatically be placed in the correct site-packages. Downside of this is that you need root or admin privileges, however starting with Python 2.6, there's also a per-user site-packages directory. On Linux systems, that will default to something like: ~/.local/lib/python2.7/site-packages/ The less boring way is to adjust your path. There are various ways to do this: (1) Set an environment variable. E.g. in my .bashrc file, I have this: export PYTHONPATH="/home/steve/python/:/home/steve/python/utilities" which will add the two ":" separated paths to sys.path. You can launch Python using a specific path like this from bash: PYTHONPATH="/tmp:$PYTHONPATH" python (Note that you have to use "" quotes, as bash doesn't evaluate environment variables inside '' quotes.) (2) If you set a PYTHONSTARTUP environment variable giving the path to a Python file, you can manipulate the path inside that: # startup.py import sys sys.path.append("something/or/other/") but be aware that the startup file only runs when you run the interactive interpreter directly, it doesn't run when you execute scripts. (3) Of course a module itself can also import sys and manipulate the path, but that doesn't help you import the module in the first instance. (4) If you're distributing an application which happens to be written in Python, one nice trick is the make the entry-point to the application (the executable file that you run) a shell script which sets up the PYTHONPATH environment variable (and any others you need) before calling Python. It doesn't have to be a shell script: you can do it in Python as well. Since the application script never gets imported, only run directly, the bootstrap problem of (3) doesn't matter. (5) If you're distributing your own Python installation, you can hack the values for sys.prefix and sys.exec_prefix, or the site.py file. But if you do that, you're on your own. (6) Create a spam.pth file listing directories to add. (7) Create a sitecustomize.py or usercustomize.py file. For (6) and (7), see the documentation for site.py: https://docs.python.org/2/library/site.html https://docs.python.org/3/library/site.html -- Steve From akleider at sonic.net Mon Oct 19 21:28:17 2015 From: akleider at sonic.net (Alex Kleider) Date: Mon, 19 Oct 2015 12:28:17 -0700 Subject: [Tutor] =?utf-8?q?accessing_modules_found_throughout_a_package=3F?= In-Reply-To: <20151019010147.GA3813@ando.pearwood.info> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> Message-ID: <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> On 2015-10-18 18:01, Steven D'Aprano wrote: > On Sun, Oct 18, 2015 at 08:07:07AM -0700, Alex Kleider wrote: >> On 2015-10-17 19:49, Steven D'Aprano wrote: >> >> >which will work from your package's callers, and from within the >> >package >> >itself provided the top level directory can be found within Python's >> >path. Within the package you can also use relative imports, see the >> >docs for more detail. >> >> How does one arrange so "the top level directory _can_ be found within >> Python's path."? Thank you, Alan, Martin, Ben and Steve. I'm a long way from distributing packages! Rather I'm simply writing scripts for personal use and would like to do it using Test Driven Development- hence my wish to be able to reference modules within my development directory. I've been able to satisfy my needs by adding export PYTHONPATH="${PYTHONPATH:+$PYTHONPATH:}/home/alex/Py" to the end of my ~/.bashrc although use of a setup.py file is probably the more 'pythonic' way of doing it. From my reading so far [1] it's not clear to me exactly how this works but a bit of experimentation might rectify that. Again, thank you. Alex [1] https://docs.python.org/3/distutils/introduction.html#distutils-simple-example From ben+python at benfinney.id.au Mon Oct 19 21:37:31 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Tue, 20 Oct 2015 06:37:31 +1100 Subject: [Tutor] Working collaboratively (was: accessing modules found throughout a package?) References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> Message-ID: <854mhmr6o4.fsf_-_@benfinney.id.au> Alex Kleider writes: > I'm a long way from distributing packages! You can keep working at your own pace, and that's good. But even better, I would strongly recommend that you work with other people early and frequently. Programming is fundamentally a process of collaboration and communication with other human programmers. The habits you form alone can be eccentric and unhelpful, with no-one to comment on strange habits you may be forming without even noticing until they are too deeply entrenched to easily avoid. Working frequently with others on the same code base will not only flush out these oddities, but also help you to appreciate the consensus decisions made in the past by the Python community as a whole. So, while it's not essential, I would heartily encourage you to pick some of the PyPI projects you are enjoying, or want to improve, and contact their maintainers with your offer to fix specific things. Work with other Python programmers on a common code base, and watch your skills broaden and improve! -- \ ?For man, as for flower and beast and bird, the supreme triumph | `\ is to be most vividly, most perfectly alive? ?D.H. Lawrence | _o__) | Ben Finney From akleider at sonic.net Mon Oct 19 21:53:40 2015 From: akleider at sonic.net (Alex Kleider) Date: Mon, 19 Oct 2015 12:53:40 -0700 Subject: [Tutor] =?utf-8?q?Working_collaboratively_=28was=3A_accessing_mod?= =?utf-8?q?ules_found_throughout_a_package=3F=29?= In-Reply-To: <854mhmr6o4.fsf_-_@benfinney.id.au> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> Message-ID: <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> On 2015-10-19 12:37, Ben Finney wrote: > Alex Kleider writes: > >> I'm a long way from distributing packages! > > You can keep working at your own pace, and that's good. But even > better, > I would strongly recommend that you work with other people early and > frequently. > > Programming is fundamentally a process of collaboration and > communication with other human programmers. > > The habits you form alone can be eccentric and unhelpful, with no-one > to > comment on strange habits you may be forming without even noticing > until > they are too deeply entrenched to easily avoid. > > Working frequently with others on the same code base will not only > flush > out these oddities, but also help you to appreciate the consensus > decisions made in the past by the Python community as a whole. > > So, while it's not essential, I would heartily encourage you to pick > some of the PyPI projects you are enjoying, or want to improve, and > contact their maintainers with your offer to fix specific things. Work > with other Python programmers on a common code base, and watch your > skills broaden and improve! How I wish I could find such collaborator! Are there any "starter level" PyPi projects the maintainer of which might consider a novice collaborator? I would have assumed that such an animal doesn't exist. I do appreciate the advice. cheers, Alex From emile at fenx.com Mon Oct 19 22:08:38 2015 From: emile at fenx.com (Emile van Sebille) Date: Mon, 19 Oct 2015 13:08:38 -0700 Subject: [Tutor] Working collaboratively In-Reply-To: <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> Message-ID: On 10/19/2015 12:53 PM, Alex Kleider wrote: > On 2015-10-19 12:37, Ben Finney wrote: >> So, while it's not essential, I would heartily encourage you to pick >> some of the PyPI projects you are enjoying, or want to improve, and >> contact their maintainers with your offer to fix specific things. Work >> with other Python programmers on a common code base, and watch your >> skills broaden and improve! > > How I wish I could find such collaborator! > Are there any "starter level" PyPi projects the maintainer of which > might consider a novice collaborator? This looks like the list of identified issues: https://bitbucket.org/pypa/pypi/issues Browse through and see if anything looks interesting/doable. Emile From breamoreboy at yahoo.co.uk Mon Oct 19 22:34:18 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 19 Oct 2015 21:34:18 +0100 Subject: [Tutor] Working collaboratively In-Reply-To: <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> Message-ID: On 19/10/2015 20:53, Alex Kleider wrote: > On 2015-10-19 12:37, Ben Finney wrote: >> Alex Kleider writes: >> >>> I'm a long way from distributing packages! >> >> You can keep working at your own pace, and that's good. But even better, >> I would strongly recommend that you work with other people early and >> frequently. >> >> Programming is fundamentally a process of collaboration and >> communication with other human programmers. >> >> The habits you form alone can be eccentric and unhelpful, with no-one to >> comment on strange habits you may be forming without even noticing until >> they are too deeply entrenched to easily avoid. >> >> Working frequently with others on the same code base will not only flush >> out these oddities, but also help you to appreciate the consensus >> decisions made in the past by the Python community as a whole. >> >> So, while it's not essential, I would heartily encourage you to pick >> some of the PyPI projects you are enjoying, or want to improve, and >> contact their maintainers with your offer to fix specific things. Work >> with other Python programmers on a common code base, and watch your >> skills broaden and improve! > > How I wish I could find such collaborator! > Are there any "starter level" PyPi projects the maintainer of which > might consider a novice collaborator? I would have assumed that > such an animal doesn't exist. > > I do appreciate the advice. > > cheers, > Alex How about https://mail.python.org/mailman/listinfo/core-mentorship ? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From sashensingh4 at gmail.com Mon Oct 19 20:23:27 2015 From: sashensingh4 at gmail.com (Sashen Singh) Date: Mon, 19 Oct 2015 20:23:27 +0200 Subject: [Tutor] Probability Density Function Message-ID: Hi, I have an array of chi square values for different values of redshift between 0 and 3. I know that the min-chi square value refers to the maximum likelihood. I need to plot a probability density function using the chi square values. I'm expecting a peak at the min-chi square. I'm having a lot of difficulty approaching this problem. Could you help me in trying to plot this. Thank you From dyoo at hashcollision.org Mon Oct 19 22:56:43 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Mon, 19 Oct 2015 13:56:43 -0700 Subject: [Tutor] Probability Density Function In-Reply-To: References: Message-ID: On Mon, Oct 19, 2015 at 11:23 AM, Sashen Singh wrote: > Hi, > I have an array of chi square values for different values of redshift > between 0 and 3. I know that the min-chi square value refers to the maximum > likelihood. I need to plot a probability density function using the chi > square values. I'm expecting a peak at the min-chi square. I'm having a lot > of difficulty approaching this problem. Could you help me in trying to plot > this. I don't think this is something we can effectively help on tutor at python.org; your question is advanced enough that I don't think there are many of us here who have enough experience to give you good answers on this. You might want to contact the scipy or matplotlib folks on this, as it seems to be in their domain. http://www.scipy.org/ http://www.scipy.org/scipylib/mailing-lists.html http://matplotlib.org/ https://mail.python.org/mailman/listinfo/matplotlib-users From lac at openend.se Mon Oct 19 23:32:49 2015 From: lac at openend.se (Laura Creighton) Date: Mon, 19 Oct 2015 23:32:49 +0200 Subject: [Tutor] Probability Density Function In-Reply-To: References: Message-ID: <201510192132.t9JLWnac019766@fido.openend.se> In a message of Mon, 19 Oct 2015 20:23:27 +0200, Sashen Singh writes: >Hi, >I have an array of chi square values for different values of redshift >between 0 and 3. I know that the min-chi square value refers to the maximum >likelihood. I need to plot a probability density function using the chi >square values. I'm expecting a peak at the min-chi square. I'm having a lot >of difficulty approaching this problem. Could you help me in trying to plot >this. >Thank you >_______________________________________________ >Tutor maillist - Tutor at python.org >To unsubscribe or change subscription options: >https://mail.python.org/mailman/listinfo/tutor This will help. http://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.stats.chi2.html Come back if you need more help getting to the point where you understand example with code, including how to plot it. Laura From akleider at sonic.net Tue Oct 20 00:04:12 2015 From: akleider at sonic.net (Alex Kleider) Date: Mon, 19 Oct 2015 15:04:12 -0700 Subject: [Tutor] Working collaboratively In-Reply-To: References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> Message-ID: <03604ad821645dd59d971a28174dedc3@sonic.net> On 2015-10-19 13:08, Emile van Sebille wrote: > This looks like the list of identified issues: > https://bitbucket.org/pypa/pypi/issues > > Browse through and see if anything looks interesting/doable. On 2015-10-19 13:34, Mark Lawrence wrote: > How about https://mail.python.org/mailman/listinfo/core-mentorship ? Thank you Emile and Mark for your suggestions. I fear that both are better suited to someone much more advanced than I! From emile at fenx.com Tue Oct 20 00:18:49 2015 From: emile at fenx.com (Emile van Sebille) Date: Mon, 19 Oct 2015 15:18:49 -0700 Subject: [Tutor] Working collaboratively In-Reply-To: <03604ad821645dd59d971a28174dedc3@sonic.net> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> <03604ad821645dd59d971a28174dedc3@sonic.net> Message-ID: On 10/19/2015 3:04 PM, Alex Kleider wrote: > On 2015-10-19 13:08, Emile van Sebille wrote: > >> This looks like the list of identified issues: >> https://bitbucket.org/pypa/pypi/issues >> >> Browse through and see if anything looks interesting/doable. > > > On 2015-10-19 13:34, Mark Lawrence wrote: > >> How about https://mail.python.org/mailman/listinfo/core-mentorship ? > > Thank you Emile and Mark for your suggestions. > I fear that both are better suited to someone much more advanced than I! You'd think so, but digging into any of the issues shown there and simply trying to locate where a change may help resolve the issue is itself a learning experience that'll do more for you taking your first step then watching from the sidelines. For example, take a look at http://bugs.python.org/issue25417 -- can you figure out what file this change may impact? (Note -- I haven't looked) Emile From zachary.ware+pytut at gmail.com Tue Oct 20 00:26:05 2015 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Mon, 19 Oct 2015 17:26:05 -0500 Subject: [Tutor] Working collaboratively (was: accessing modules found throughout a package?) In-Reply-To: <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> Message-ID: On Mon, Oct 19, 2015 at 2:53 PM, Alex Kleider wrote: > On 2015-10-19 12:37, Ben Finney wrote: >> Work >> with other Python programmers on a common code base, and watch your >> skills broaden and improve! > > > How I wish I could find such collaborator! > Are there any "starter level" PyPi projects the maintainer of which > might consider a novice collaborator? I would have assumed that > such an animal doesn't exist. Most maintainers of open source software will gratefully accept patches from anybody of any skill level (after proper review), though there's always the possibility that a patch will be politely rejected (if it's rejected impolitely, that's their problem, not yours). The choice of project to contribute to is really up to you. Pick one that you like and know fairly well, and preferably make a contribution that will make some difference to you and your use of the project. And if you can't find a PyPI project you'd like to contribute to, you could always give a shot to working on CPython itself -- see https://docs.python.org/devguide/ for a guide to getting started with that. -- Zach From breamoreboy at yahoo.co.uk Tue Oct 20 00:33:51 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Mon, 19 Oct 2015 23:33:51 +0100 Subject: [Tutor] Working collaboratively In-Reply-To: <03604ad821645dd59d971a28174dedc3@sonic.net> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> <03604ad821645dd59d971a28174dedc3@sonic.net> Message-ID: On 19/10/2015 23:04, Alex Kleider wrote: > On 2015-10-19 13:08, Emile van Sebille wrote: > >> This looks like the list of identified issues: >> https://bitbucket.org/pypa/pypi/issues >> >> Browse through and see if anything looks interesting/doable. > > > On 2015-10-19 13:34, Mark Lawrence wrote: > >> How about https://mail.python.org/mailman/listinfo/core-mentorship ? > > Thank you Emile and Mark for your suggestions. > I fear that both are better suited to someone much more advanced than I! > To be frank what difference does it make? Whether a project on pypi or core Python you're still going to be learning. Further the core mentorship list is specifically there to assist. If you try and fail so what? If you don't try you'll never know. You might also like to know that by nature I'm so shy that it took me months if not years to pluck up the courage to join in with any online community. In a lot of ways I made a complete fool of myself. I learned. So can you :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Tue Oct 20 01:47:00 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 20 Oct 2015 10:47:00 +1100 Subject: [Tutor] Working collaboratively In-Reply-To: References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> Message-ID: <20151019234700.GH3813@ando.pearwood.info> On Mon, Oct 19, 2015 at 09:34:18PM +0100, Mark Lawrence wrote: > On 19/10/2015 20:53, Alex Kleider wrote: > >Are there any "starter level" PyPi projects the maintainer of which > >might consider a novice collaborator? I would have assumed that > >such an animal doesn't exist. > > > >I do appreciate the advice. > How about https://mail.python.org/mailman/listinfo/core-mentorship ? While core-mentorship is open to all, it is intended "for developers interested in contributing to core Python development", which means that the intent is to teach *experienced* programmers how to deal with the specific indiosyncracies of the CPython code base and development process. It's also quite low volume. Have a read of: https://docs.python.org/devguide/ particularly the FAQs and see if it looks like something you can handle. I emphasis that you don't need core-mentorship in order to provide patches for issues on the Python bug tracker. You could dip your toe in the water by finding some easy issues and submitting patches, even just doc patches: http://bugs.python.org Personally, what worked for me (although at the cost of many, many hours over the years!) was reading and discussing other people's code, here and on comp.lang.python (also available via email, python-list at python.org), reading the standard library code to see how it works, and especially reading the recipes in the Python Cookbook (O'Reilly Books) and ActiveState: http://code.activestate.com/recipes/langs/python/ although sometimes the quality is a bit mixed. Even the top-rated recipes are not immune to this: http://code.activestate.com/recipes/langs/python/top/ (although generally anything by Raymond Hettinger is almost guaranteed to be amazing). For example, I just came across a top-rated recipe for dependency injection which doesn't actually implement dependency injection. (That's a good trick, since dependency injection is *trivially* easy in Python.) -- Steve From steve at pearwood.info Tue Oct 20 02:03:17 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 20 Oct 2015 11:03:17 +1100 Subject: [Tutor] Working collaboratively In-Reply-To: References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> <03604ad821645dd59d971a28174dedc3@sonic.net> Message-ID: <20151020000316.GI3813@ando.pearwood.info> On Mon, Oct 19, 2015 at 11:33:51PM +0100, Mark Lawrence wrote: > You might also like to know that by nature I'm so shy http://i0.wp.com/memecollection.net/wp-content/uploads/2013/03/be-nice-im-shy.jpg?w=900 :-) -- Steve From akleider at sonic.net Tue Oct 20 08:33:25 2015 From: akleider at sonic.net (Alex Kleider) Date: Mon, 19 Oct 2015 23:33:25 -0700 Subject: [Tutor] Working collaboratively In-Reply-To: References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> <03604ad821645dd59d971a28174dedc3@sonic.net> Message-ID: <5f38cbae0c54a511599b9190674f6f4b@sonic.net> On 2015-10-19 15:18, Emile van Sebille wrote: > On 10/19/2015 3:04 PM, Alex Kleider wrote: >> On 2015-10-19 13:08, Emile van Sebille wrote: >> >>> This looks like the list of identified issues: >>> https://bitbucket.org/pypa/pypi/issues >>> >>> Browse through and see if anything looks interesting/doable. >> >> >> On 2015-10-19 13:34, Mark Lawrence wrote: >> >>> How about https://mail.python.org/mailman/listinfo/core-mentorship ? >> >> Thank you Emile and Mark for your suggestions. >> I fear that both are better suited to someone much more advanced than >> I! > > You'd think so, but digging into any of the issues shown there and > simply trying to locate where a change may help resolve the issue is > itself a learning experience that'll do more for you taking your first > step then watching from the sidelines. > > For example, take a look at http://bugs.python.org/issue25417 -- can > you figure out what file this change may impact? (Note -- I haven't > looked) > > Emile Inspired by your encouragement (for which I'm grateful,) I had a look: Here's the content of issue25417: """ The output of pydoc for Path.samefile currently reads pathlib.Path.samefile = samefile(self, other_path) Return whether `other_file` is the same or not as this file. (as returned by os.path.samefile(file, other_file)). It should arguably be something like pathlib.Path.samefile = samefile(self, other_path) Return whether `other_path` is the same or not as this file. (as returned by os.path.samefile(file, other_file)). or pathlib.Path.samefile = samefile(self, other_path) Return whether `other_path` is the same or not as this file. (as returned by os.path.samefile(str(self), str(other_path))). """ The author suggests that the output A should in fact be more along the lines of B or C but to my reading A==B==C! Am I missing something? I did look at the source: https://hg.python.org/cpython/file/3.5/Lib/pydoc.py How would one download the source? (i.e. the equivalent of git clone ...) Thanks, ak From alan.gauld at btinternet.com Tue Oct 20 10:02:46 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 20 Oct 2015 09:02:46 +0100 Subject: [Tutor] Working collaboratively In-Reply-To: <5f38cbae0c54a511599b9190674f6f4b@sonic.net> References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> <03604ad821645dd59d971a28174dedc3@sonic.net> <5f38cbae0c54a511599b9190674f6f4b@sonic.net> Message-ID: On 20/10/15 07:33, Alex Kleider wrote: > The output of pydoc for Path.samefile currently reads > > pathlib.Path.samefile = samefile(self, other_path) > Return whether `other_file` is the same or not as this file. > > pathlib.Path.samefile = samefile(self, other_path) > Return whether `other_path` is the same or not as this file. Look closely at what the return value is called in each case. And see how it compares to the names in the signature. -- 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 soweto at gmail.com Tue Oct 20 13:29:59 2015 From: soweto at gmail.com (Vusa Moyo) Date: Tue, 20 Oct 2015 13:29:59 +0200 Subject: [Tutor] Help with return results statement. Message-ID: Hi there. My script is as follows, lloyd = { "name": "Lloyd", "homework": [90.0, 97.0, 75.0, 92.0], "quizzes": [88.0, 40.0, 94.0], "tests": [75.0, 90.0] } alice = { "name": "Alice", "homework": [100.0, 92.0, 98.0, 100.0], "quizzes": [82.0, 83.0, 91.0], "tests": [89.0, 97.0] } tyler = { "name": "Tyler", "homework": [0.0, 87.0, 75.0, 22.0], "quizzes": [0.0, 75.0, 78.0], "tests": [100.0, 100.0] } # Add your function below! def average(numbers): total = sum(numbers) total = float(total) total = total / len(numbers) return total def get_average(student): homework = average(student["homework"]) quizzes = average(student["quizzes"]) tests = average(student["tests"]) return 0.1 * homework + 0.3 * quizzes + 0.6 * tests def get_letter_grade(score): if score >= 90: return "A" elif score >= 80: return "B" elif score >= 70: return "C" elif score >= 60: return "D" else: return "F" print get_average(lloyd) def get_class_average(students): results = [] for a in students: b = int(get_average(a)) results.append([b]) return results ===== When I pass get_class_average(alice) I receive a zero value for results, which doesnt quite make sense to me. please explain how I'm getting this wrong. Regards From steve at pearwood.info Tue Oct 20 14:25:54 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Tue, 20 Oct 2015 23:25:54 +1100 Subject: [Tutor] Help with return results statement. In-Reply-To: References: Message-ID: <20151020122552.GJ3813@ando.pearwood.info> Hi Vusa, and welcome. On Tue, Oct 20, 2015 at 01:29:59PM +0200, Vusa Moyo wrote: > Hi there. My script is as follows, [...] > def get_class_average(students): > results = [] > for a in students: > b = int(get_average(a)) > results.append([b]) > return results I'm not sure why you are getting 0, but the get_class_average function is definitely wrong. The problem is in the structure of the function. You have the *return* inside the for-loop, which means that only the first student will ever be processed. As soon as the function gets to the "return results" line, it will exit the for-loop leaving everything else unprocessed. You need to unindent the return so it looks like this: def get_class_average(students): results = [] for a in students: b = int(get_average(a)) results.append([b]) return results Now the for-loop will run all the way to the end, and the function will only return at the very end. I'm also not entirely sure about the [b] argument to append. Are you sure it is supposed to be [b]? That will be appending a *list* consisting of a single value. I think you want: results.append(b) without the square brackets. Why don't you try both and see the difference? -- Steve From alan.gauld at btinternet.com Tue Oct 20 14:38:51 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 20 Oct 2015 13:38:51 +0100 Subject: [Tutor] Help with return results statement. In-Reply-To: References: Message-ID: On 20/10/15 12:29, Vusa Moyo wrote: > Hi there. My script is as follows, > alice = { > "name": "Alice", > "homework": [100.0, 92.0, 98.0, 100.0], > "quizzes": [82.0, 83.0, 91.0], > "tests": [89.0, 97.0] > } > # Add your function below! > def average(numbers): > total = sum(numbers) > total = float(total) That line isn't necessary since the inputs are floats already. > total = total / len(numbers) > return total > > def get_average(student): > homework = average(student["homework"]) > quizzes = average(student["quizzes"]) > tests = average(student["tests"]) > return 0.1 * homework + 0.3 * quizzes + 0.6 * tests > > def get_letter_grade(score): > if score >= 90: > return "A" > elif score >= 80: > return "B" > print get_average(lloyd) > > def get_class_average(students): > results = [] > for a in students: > b = int(get_average(a)) > results.append([b]) > return results > > get_class_average(alice) > > I receive a zero value for results, which doesnt quite make sense to me. Nor to me. Are you sure its a zero result? It should be a list of some kind not a number. Or do you mean you get an empty list back? Notice that get_class_average() expects your students value to be some kind of sequence or collection. The for loop will iterate over that. If you pass Alice as a single student it will iterate over the keys, trying first of all to get the average of "Alice" which should fail with an error. Did you get any errors? If so please let us see them. Please show us the actual code you execute, the actual output and the full text of any errors. One other thing that seems weird to me is that you go to great pains to produce a float as a result of get_average() but then you immediately convert it to an int. Why not leave it as a float? -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From akleider at sonic.net Tue Oct 20 17:29:32 2015 From: akleider at sonic.net (Alex Kleider) Date: Tue, 20 Oct 2015 08:29:32 -0700 Subject: [Tutor] Working collaboratively In-Reply-To: References: <20151018024946.GC3725@ando.pearwood.info> <9565bc89db0c281f42d4c4a0a7149b30@sonic.net> <20151019010147.GA3813@ando.pearwood.info> <7a41e1d7a9c3db2dbaddf4fc0e74de04@sonic.net> <854mhmr6o4.fsf_-_@benfinney.id.au> <1675fa1a6ce0874c33a48f829d3b9103@sonic.net> <03604ad821645dd59d971a28174dedc3@sonic.net> <5f38cbae0c54a511599b9190674f6f4b@sonic.net> Message-ID: <3329005450e0141c2b26bc0502b287d8@sonic.net> On 2015-10-20 01:02, Alan Gauld wrote: > On 20/10/15 07:33, Alex Kleider wrote: > Look closely at what the return value is called in each case. > And see how it compares to the names in the signature. OOPS! Should have run over them with diff _before_ posting rather than after. Sorry about that. Alex From nymcity at yahoo.com Wed Oct 21 02:18:37 2015 From: nymcity at yahoo.com (Nym City) Date: Wed, 21 Oct 2015 00:18:37 +0000 (UTC) Subject: [Tutor] Custom Function that Takes argument In-Reply-To: <561C508C.9040707@btinternet.com> References: <561C508C.9040707@btinternet.com> Message-ID: <2052831293.619415.1445386717916.JavaMail.yahoo@mail.yahoo.com> Hello, Thank you for your feedback. Sorry it took me a while to revise my code but here is my code with the changes: import urllib2 import json locu_api = 'redacted' def locu_search(query): ??? api_key = locu_api ??? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key ??? locality = query.replace(' ', '%20') ??? final_url = url + '&locality=' + locality + "&category=restaurant" ??? jason_obj = urllib2.urlopen(final_url) ??? data = json.load(jason_obj) ??? for item in data['objects']: ??????? print item['name'], item['phone'], item['street_address'] def region_search(query): ??? api_key = locu_api ??? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key ??? region = query.replace(' ', '%20') ??? final_url = url + '®ion=' + region + "&category=restaurant" ??? jason_obj = urllib2.urlopen(final_url) ??? data = json.load(jason_obj) ??? for item in data['objects']: ??????? print item['name'], item['phone'], item['street_address'], item['locality'], item['website_url'] def zip_search(query): ??? api_key = locu_api ??? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key ??? zip = query.replace(' ', '%20') ??? final_url = url + '&zip=' + zip + "&category=restaurant" ??? jason_obj = urllib2.urlopen(final_url) ??? data = json.load(jason_obj) ??? for item in data['objects']: ??????? print item['name'], item['phone'], item['street_address'], item['categories'], item['website_url'] ans=True while ans: ??? print (""" ??? 1.Search by City ??? 2.Search by Region (State Abbreviation) ??? 3.Search by Zip ??? 4.Exit/Quit ??? """) ??? ans=raw_input("What would you like to do? ") ??? if ans=="1": ????? locality = raw_input("\nEnter City ") ????? print locu_search(locality) ????? break ??? elif ans=="2": ??????? region = raw_input("\n Search by State ") ??????? print region_search(region) ??????? break ??? elif ans=="3": ??????? zip = raw_input("\n Search by Zip ") ??????? print zip_search(zip) ??????? break ??? elif ans=="4": ????? print("\n Goodbye") ????? break? ----- I am not sure if above changes exactly reflect your suggestions but I tested the logic and it seems to work. The only issue is that on the first two queries (locu_search(locality) and region_search(region)) I receive the following traceback error: Traceback (most recent call last): ? File "C:/Users/dell/Documents/Python/MyProject/API_Projects/locu/locuAPI.py", line 47, in ??? print locu_search(locality) ? File "C:/Users/dell/Documents/Python/MyProject/API_Projects/locu/locuAPI.py", line 14, in locu_search ??? print item['name'], item['phone'], item['street_address'] ? File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode ??? return codecs.charmap_encode(input,errors,encoding_table) UnicodeEncodeError: 'charmap' codec can't encode character u'\u200e' in position 29: character maps to The last query about zip definition works perfectly. Please share thoughts on the revised logic and recommendation for handling the error above. Thanks! Please Thank you. On Monday, October 12, 2015 8:30 PM, Alan Gauld wrote: On 13/10/15 00:32, Nym City wrote: > > ans=raw_input("What would you like to do? ") >? ? if ans=="1": >? ? ? locality = raw_input("\nEnter City ") >? ? ? break >? ? elif ans=="2": >? ? ? ? region = raw_input("\n Search by State ") >? ? ? ? break >? ? elif ans=="3": >? ? ? ? zip = raw_input("\n Search by Zip ") >? ? ? ? break >? ? elif ans=="4": >? ? ? print("\n Goodbye") >? ? ? break > ...? The use case is that by not knowing which of the 4 options the > user will select, But you know what they select after they have done it so you need to wait till that point to run the appropriate? query. And ans tells you which choice the user made. > NameError: name 'locality' is not defined > > -------- > The error points back to where this is: > > varibles = [locu_search(locality), region_search(region), zip_search(zip)] > > I don't understand why Python thinks that locality (and others) are > not defined when I defined them at the very beginning. > You didn't. You only define them once the user makes a choice. eg. If the ans is 3 then locality and region are not defined. But even if they were (with default values) you don;t want to run all the queries each time. Only run the query selected by the user. So call the query functions in the if/else structure where you set the variables. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Wed Oct 21 11:52:30 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 21 Oct 2015 10:52:30 +0100 Subject: [Tutor] Custom Function that Takes argument In-Reply-To: <2052831293.619415.1445386717916.JavaMail.yahoo@mail.yahoo.com> References: <561C508C.9040707@btinternet.com> <2052831293.619415.1445386717916.JavaMail.yahoo@mail.yahoo.com> Message-ID: On 21/10/15 01:18, Nym City via Tutor wrote: > def zip_search(query): > api_key = locu_api > url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key > zip = query.replace(' ', '%20') > final_url = url + '&zip=' + zip + "&category=restaurant" > jason_obj = urllib2.urlopen(final_url) > data = json.load(jason_obj) > for item in data['objects']: > print item['name'], item['phone'], item['street_address'], item['categories'], item['website_url'] > > ans=True > while ans: > print (""" > 1.Search by City > 2.Search by Region (State Abbreviation) > 3.Search by Zip > 4.Exit/Quit > """) > ans=raw_input("What would you like to do? ") > if ans=="1": > locality = raw_input("\nEnter City ") > print locu_search(locality) > break > elif ans=="2": > region = raw_input("\n Search by State ") > print region_search(region) > break > elif ans=="3": > zip = raw_input("\n Search by Zip ") > print zip_search(zip) > break > elif ans=="4": > print("\n Goodbye") > break Because you now process the results in the if clauses you no longer need the breaks. In fact if you want the menu to be repeated you need to take them all out except for the last one. > ----- > I am not sure if above changes exactly reflect your suggestions but I tested the logic and it seems to work. > > The only issue is that on the first two queries (locu_search(locality) and > region_search(region)) I receive the following traceback error: > Traceback (most recent call last): > File "C:/Users/dell/Documents/Python/MyProject/API_Projects/locu/locuAPI.py", line 47, in > print locu_search(locality) > File "C:/Users/dell/Documents/Python/MyProject/API_Projects/locu/locuAPI.py", line 14, in locu_search > print item['name'], item['phone'], item['street_address'] > File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode > return codecs.charmap_encode(input,errors,encoding_table) > UnicodeEncodeError: 'charmap' codec can't encode character u'\u200e' in position 29: character maps to Looks like you are using cpl252 and your data is coming back as something else (UTF-8 maybe?) so you probably need to specify the encoding. -- 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 soweto at gmail.com Thu Oct 22 11:03:53 2015 From: soweto at gmail.com (Vusa Moyo) Date: Thu, 22 Oct 2015 11:03:53 +0200 Subject: [Tutor] Help with return results statement. In-Reply-To: References: Message-ID: Hi Guys. Thanks for the responses and assistance. I came right after-all. The last 2 blocks read the following. def get_class_average(students): results = [] for a in students: b = float(get_average(a)) results.append(b) return average(results) students = [lloyd, alice, tyler] print(get_class_average(students)) bother = get_class_average([lloyd, alice, tyler]) print(get_letter_grade(bother)) Worked like a charm. Thanks for the assistance. Regards Vusa On Tue, Oct 20, 2015 at 2:38 PM, Alan Gauld wrote: > On 20/10/15 12:29, Vusa Moyo wrote: > >> Hi there. My script is as follows, >> > > alice = { >> "name": "Alice", >> "homework": [100.0, 92.0, 98.0, 100.0], >> "quizzes": [82.0, 83.0, 91.0], >> "tests": [89.0, 97.0] >> } >> > > # Add your function below! >> def average(numbers): >> > > total = sum(numbers) > > total = float(total) > > That line isn't necessary since the inputs are floats already. > > > total = total / len(numbers) > > return total > > > >> def get_average(student): >> homework = average(student["homework"]) >> quizzes = average(student["quizzes"]) >> tests = average(student["tests"]) >> return 0.1 * homework + 0.3 * quizzes + 0.6 * tests >> >> def get_letter_grade(score): >> if score >= 90: >> return "A" >> elif score >= 80: >> return "B" >> > > print get_average(lloyd) >> >> def get_class_average(students): >> results = [] >> for a in students: >> b = int(get_average(a)) >> results.append([b]) >> return results >> >> > get_class_average(alice) >> >> I receive a zero value for results, which doesnt quite make sense to me. >> > > Nor to me. Are you sure its a zero result? It should be a list of some > kind not a number. Or do you mean you get an empty list back? > > Notice that get_class_average() expects your students value to be > some kind of sequence or collection. The for loop will iterate over that. > If you pass Alice as a single student it will iterate over the keys, trying > first of all to get the average of "Alice" which should fail with an error. > Did you get any errors? If so please let us see them. > > Please show us the actual code you execute, the actual output > and the full text of any errors. > > One other thing that seems weird to me is that you go to great pains to > produce a float as a result of get_average() but then you > immediately convert it to an int. Why not leave it as a float? > > > -- > 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 btinternet.com Thu Oct 22 11:14:49 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Thu, 22 Oct 2015 10:14:49 +0100 Subject: [Tutor] Help with return results statement. In-Reply-To: References: Message-ID: <5628A909.9010404@btinternet.com> On 22/10/15 10:03, Vusa Moyo wrote: > Hi Guys. Thanks for the responses and assistance. > > I came right after-all. The last 2 blocks read the following. Glad you are happy but there is still something you could improve: > def get_class_average(students): > results = [] > for a in students: > b = float(get_average(a)) You really don't need the float() here. get_average() is guaranteed to return a float. > results.append(b) > return average(results) > > > students = [lloyd, alice, tyler] > print(get_class_average(students)) > bother = get_class_average([lloyd, alice, tyler]) > print(get_letter_grade(bother)) > > Worked like a charm. > > Thanks for the assistance. > > Regards > > Vusa > > > On Tue, Oct 20, 2015 at 2:38 PM, Alan Gauld > wrote: > > On 20/10/15 12:29, Vusa Moyo wrote: > > Hi there. My script is as follows, > > > alice = { > "name": "Alice", > "homework": [100.0, 92.0, 98.0, 100.0], > "quizzes": [82.0, 83.0, 91.0], > "tests": [89.0, 97.0] > } > > > # Add your function below! > def average(numbers): > > > total = sum(numbers) > > total = float(total) > > That line isn't necessary since the inputs are floats already. > > > total = total / len(numbers) > > return total > > > > def get_average(student): > homework = average(student["homework"]) > quizzes = average(student["quizzes"]) > tests = average(student["tests"]) > return 0.1 * homework + 0.3 * quizzes + 0.6 * tests > > def get_letter_grade(score): > if score >= 90: > return "A" > elif score >= 80: > return "B" > > > print get_average(lloyd) > > def get_class_average(students): > results = [] > for a in students: > b = int(get_average(a)) > results.append([b]) > return results > > > get_class_average(alice) > > I receive a zero value for results, which doesnt quite make > sense to me. > > > Nor to me. Are you sure its a zero result? It should be a list of > some kind not a number. Or do you mean you get an empty list back? > > Notice that get_class_average() expects your students value to be > some kind of sequence or collection. The for loop will iterate > over that. If you pass Alice as a single student it will iterate > over the keys, trying first of all to get the average of "Alice" > which should fail with an error. Did you get any errors? If so > please let us see them. > > Please show us the actual code you execute, the actual output > and the full text of any errors. > > One other thing that seems weird to me is that you go to great > pains to produce a float as a result of get_average() but then you > immediately convert it to an int. Why not leave it as a float? > > > -- > 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 > > -- 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 soweto at gmail.com Thu Oct 22 11:31:22 2015 From: soweto at gmail.com (Vusa Moyo) Date: Thu, 22 Oct 2015 11:31:22 +0200 Subject: [Tutor] Help with return results statement. In-Reply-To: <5628A909.9010404@btinternet.com> References: <5628A909.9010404@btinternet.com> Message-ID: Thanks Alan. Removed that . ===== # Add your functions below! def average(numbers): total = sum(numbers) total = total / len(numbers) return total def get_average(student): homework = average(student["homework"]) quizzes = average(student["quizzes"]) tests = average(student["tests"]) return 0.1 * homework + 0.3 * quizzes + 0.6 * tests def get_letter_grade(score): if score >= 90: return "A" elif score >= 80: return "B" elif score >= 70: return "C" elif score >= 60: return "D" else: return "F" #Class average def get_class_average(students): results = [] for a in students: b = float(get_average(a)) results.append(b) return average(results) # prompt for results. students = [lloyd, alice, tyler] print(get_class_average(students)) bother = get_class_average([lloyd, alice, tyler]) print(get_letter_grade(bother)) ===== Appreciate it. Regards Vusa On Thu, Oct 22, 2015 at 11:14 AM, Alan Gauld wrote: > On 22/10/15 10:03, Vusa Moyo wrote: > >> Hi Guys. Thanks for the responses and assistance. >> >> I came right after-all. The last 2 blocks read the following. >> > > Glad you are happy but there is still something you could improve: > > def get_class_average(students): >> results = [] >> for a in students: >> b = float(get_average(a)) >> > > You really don't need the float() here. get_average() is guaranteed > to return a float. > > results.append(b) >> return average(results) >> >> >> students = [lloyd, alice, tyler] >> print(get_class_average(students)) >> bother = get_class_average([lloyd, alice, tyler]) >> print(get_letter_grade(bother)) >> >> Worked like a charm. >> >> Thanks for the assistance. >> >> Regards >> >> Vusa >> >> >> On Tue, Oct 20, 2015 at 2:38 PM, Alan Gauld > > wrote: >> >> On 20/10/15 12:29, Vusa Moyo wrote: >> >> Hi there. My script is as follows, >> >> >> alice = { >> "name": "Alice", >> "homework": [100.0, 92.0, 98.0, 100.0], >> "quizzes": [82.0, 83.0, 91.0], >> "tests": [89.0, 97.0] >> } >> >> >> # Add your function below! >> def average(numbers): >> >> > total = sum(numbers) >> > total = float(total) >> >> That line isn't necessary since the inputs are floats already. >> >> > total = total / len(numbers) >> > return total >> > >> >> def get_average(student): >> homework = average(student["homework"]) >> quizzes = average(student["quizzes"]) >> tests = average(student["tests"]) >> return 0.1 * homework + 0.3 * quizzes + 0.6 * tests >> >> def get_letter_grade(score): >> if score >= 90: >> return "A" >> elif score >= 80: >> return "B" >> >> >> print get_average(lloyd) >> >> def get_class_average(students): >> results = [] >> for a in students: >> b = int(get_average(a)) >> results.append([b]) >> return results >> >> >> get_class_average(alice) >> >> I receive a zero value for results, which doesnt quite make >> sense to me. >> >> >> Nor to me. Are you sure its a zero result? It should be a list of >> some kind not a number. Or do you mean you get an empty list back? >> >> Notice that get_class_average() expects your students value to be >> some kind of sequence or collection. The for loop will iterate >> over that. If you pass Alice as a single student it will iterate >> over the keys, trying first of all to get the average of "Alice" >> which should fail with an error. Did you get any errors? If so >> please let us see them. >> >> Please show us the actual code you execute, the actual output >> and the full text of any errors. >> >> One other thing that seems weird to me is that you go to great >> pains to produce a float as a result of get_average() but then you >> immediately convert it to an int. Why not leave it as a float? >> >> >> -- 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 >> >> >> > > -- > 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 danny.yoo at gmail.com Thu Oct 22 21:07:50 2015 From: danny.yoo at gmail.com (Danny Yoo) Date: Thu, 22 Oct 2015 12:07:50 -0700 Subject: [Tutor] Help with return results statement. In-Reply-To: References: <5628A909.9010404@btinternet.com> Message-ID: An additional suggestion: > ===== > # Add your functions below! > def average(numbers): > total = sum(numbers) > total = total / len(numbers) > return total Don't re-assign total here. The problem is that conceptually "total" no longer represents the total in the second assignment. It makes the name meaningless. One way to resolve the problem is to just return the value. ################# def average(numbers): total = sum(numbers) return total / len(numbers) ################# That is, the problem isn't one of computation, but of compassion. Help make code readable. From breamoreboy at yahoo.co.uk Fri Oct 23 19:15:02 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 24 Oct 2015 00:15:02 +0100 Subject: [Tutor] Scraping Wikipedia Table (The retruned file is empty) In-Reply-To: References: Message-ID: On 23/10/2015 03:31, Danny Yoo wrote: > On Thu, Oct 22, 2015 at 4:01 PM, Cynthia Alice Andrews > wrote: >> At this point I feel like I am wasting my time by not asking for help. I >> can't figure out why the file keeps coming back empty. There are no error >> message, just an empy file. Very frustrating. > > > Looking more at the code... > > > for x in range(len(drama_actor)): > > This looks unusual. drama_actor is just a single string: ranging > across the characters of a string looks very unusual. Are you sure > you want to do this? > A better question IMHO is "where did you learn to write code like that in the first place", as I've seen so many examples of this that I cannot understand why people bother writing Python tutorials, as they clearly don't get read? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From evolution5487 at gmail.com Sun Oct 25 19:16:30 2015 From: evolution5487 at gmail.com (bob5487) Date: Sun, 25 Oct 2015 16:16:30 -0700 (PDT) Subject: [Tutor] noob python question Message-ID: <1445814990929-5174789.post@n6.nabble.com> Howdy! Reading *Learn Python the Hard Way* Zed Shaw All good so far but got to Ex 42 dealing with classes... I get a TypeError: getattr(): attribute name must be a string when I run the program... I looked online, python reference manual 3rd edition, etc... I was wondering if anyone has experience with this book because I hit a road block -- View this message in context: http://python.6.x6.nabble.com/noob-python-question-tp5174789.html Sent from the Python - tutor mailing list archive at Nabble.com. From alan.gauld at btinternet.com Sun Oct 25 21:48:33 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 26 Oct 2015 01:48:33 +0000 Subject: [Tutor] Python mail server outage Message-ID: You may have noticed that the list has been quite of late due to Python mailman server having been dead for the past few days. It seems to be back up again (thanks to somebody for that!). If you posted anything recently and it hasn't appeared please give it a day or so in case there are queues to flush somewhere, if it still hasn't appeared feel free to repost. -- Alan G List moderator From alan.gauld at btinternet.com Sun Oct 25 21:56:54 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 26 Oct 2015 01:56:54 +0000 Subject: [Tutor] Scraping Wikipedia Table (The retruned file is empty) In-Reply-To: References: Message-ID: On 24/10/15 00:15, Mark Lawrence wrote: >> Looking more at the code... >> >> > for x in range(len(drama_actor)): >> >> This looks unusual... > > A better question IMHO is "where did you learn to write code like that > in the first place", as I've seen so many examples of this that I cannot > understand why people bother writing Python tutorials, as they clearly > don't get read? > I think its just a case of bad habits from other languages being hard to shake off. If your language doesn't have a for-each operator then its hard to wrap your brain around any other kind of for loop than one based on indexes. It's a bit like dictionaries. They are super powerful but beginners coming from other languages nearly always start out using arrays(ie lists) and trying to "index" them by searching which is hugely more complex, but it's what they are used too. JavaScript programmers tend to think the same about Python programmers who insist on writing separate functions for call backs rather than just embedding an anonymous function. But Python programmers are used to brain dead lambdas with a single expression so they don't tend to think about embedding a full function. Familiarity with an idiom makes it easier to stick with what you know than to try something new. -- 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 Oct 25 22:43:52 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Mon, 26 Oct 2015 13:43:52 +1100 Subject: [Tutor] noob python question References: <1445814990929-5174789.post@n6.nabble.com> Message-ID: <85twpemjrr.fsf@benfinney.id.au> bob5487 writes: > Reading *Learn Python the Hard Way* Zed Shaw > > All good so far but got to Ex 42 dealing with classes... Can you give a URL to the exact code so that we can know we're seeing the same thing that you are? > I get a TypeError: getattr(): attribute name must be a string when I > run the program... Please show the full text of the traceback, and preferably the code you ran which led to that error. -- \ ?The WWW is exciting because Microsoft doesn't own it, and | `\ therefore, there's a tremendous amount of innovation | _o__) happening.? ?Steve Jobs | Ben Finney From cs at zip.com.au Mon Oct 26 00:22:48 2015 From: cs at zip.com.au (Cameron Simpson) Date: Mon, 26 Oct 2015 15:22:48 +1100 Subject: [Tutor] noob python question In-Reply-To: <1445814990929-5174789.post@n6.nabble.com> References: <1445814990929-5174789.post@n6.nabble.com> Message-ID: <20151026042248.GA12522@cskk.homeip.net> On 25Oct2015 16:16, bob5487 wrote: >Reading *Learn Python the Hard Way* Zed Shaw >All good so far but got to Ex 42 dealing with classes... > >I get a TypeError: getattr(): attribute name must be a string when I run the >program... > >I looked online, python reference manual 3rd edition, etc... >I was wondering if anyone has experience with this book because I hit a road >block As always with this list, please post the code you're trying. Even if we had the book (I do not, personally), we don't know if your failing code matches the code in the book, or if the code in the book is correct. So please post the code, and the complete error message your computer gives you. Also not that getattr takes a string, per the error message. So to fetch the .foo attribute from some object "o" you would write: attribute = getattr(o, 'foo') Note the quotes. CHeers, Cameron Simpson From pasokan at gmail.com Mon Oct 26 02:27:29 2015 From: pasokan at gmail.com (Asokan Pichai) Date: Mon, 26 Oct 2015 11:57:29 +0530 Subject: [Tutor] noob python question In-Reply-To: <1445814990929-5174789.post@n6.nabble.com> References: <1445814990929-5174789.post@n6.nabble.com> Message-ID: Can you retype the question and your code? On 26 October 2015 at 04:46, bob5487 wrote: > Howdy! > > Reading *Learn Python the Hard Way* Zed Shaw > > All good so far but got to Ex 42 dealing with classes... > > I get a TypeError: getattr(): attribute name must be a string when I run > the > program... > > I looked online, python reference manual 3rd edition, etc... > > I was wondering if anyone has experience with this book because I hit a > road > block > > > > > > -- > View this message in context: > http://python.6.x6.nabble.com/noob-python-question-tp5174789.html > Sent from the Python - tutor mailing list archive at Nabble.com. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- Asokan Pichai *-------------------* We will find a way. Or, make one. (Hannibal) *To find everything profound ? that is an inconvenient trait.* It makes one strain one's eyes all the time, and in the end one finds more than one might have wished. -- Nietzsche From robertvstepp at gmail.com Mon Oct 26 09:54:33 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Mon, 26 Oct 2015 08:54:33 -0500 Subject: [Tutor] noob python question In-Reply-To: <1445814990929-5174789.post@n6.nabble.com> References: <1445814990929-5174789.post@n6.nabble.com> Message-ID: Greetings! On Sun, Oct 25, 2015 at 6:16 PM, bob5487 wrote: > Howdy! > > Reading *Learn Python the Hard Way* Zed Shaw > > All good so far but got to Ex 42 dealing with classes... > > I get a TypeError: getattr(): attribute name must be a string when I run the > program... > > I looked online, python reference manual 3rd edition, etc... > > I was wondering if anyone has experience with this book because I hit a road > block As many will not have access to this book, what is usually done here is to copy and paste your code as well as your FULL error message into a plain text email. Also, it is usually helpful to state your Python version and OS type and version. This will give everyone the information they need to help you. Also, you probably need to summarize what exercise 42 is asking you to do. I have a copy of that book at home. If memory serves me correctly, it is written for Python 2. If that is the case you probably want to be looking at the Python 2 documentation. Also, if you are trying to run Python 2 code and you have Python 3 installed on your computer, you will from time to time run into issues just because there ARE differences between Python 2 and 3 syntax in some areas. HTH, -- boB From lucasmascia at gmail.com Mon Oct 26 08:21:37 2015 From: lucasmascia at gmail.com (Lucas Mascia) Date: Mon, 26 Oct 2015 10:21:37 -0200 Subject: [Tutor] Python excel filter Message-ID: Hello, I would like some guidance in a way to filter data from an excel sheet (.xlsx) I will be exporting an extensive table from a website with 400x20 infos. In this sheet, I need to apply 3 or 4 filters and collect the amount of info it shows then. Eg.: 1 - Export .xlsx from website 2 - Run python to filter 2.1 - Filter by client A 2.2 - Filter by task A 2.3 - Filter by Person A 3 - Repeat filter for different clients, tasks and persons 4 - Collect the amount each person does inside each client. Please Help guide my through a starting poing Thank you, Lucas R. Mascia | VIEW MY | "It is not the strongest of the species that survives, nor the most intelligent that survives. It is the one that is most adaptable to change." - Darwin. From alan.gauld at btinternet.com Mon Oct 26 10:57:20 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Mon, 26 Oct 2015 14:57:20 +0000 Subject: [Tutor] Python excel filter In-Reply-To: References: Message-ID: On 26/10/15 12:21, Lucas Mascia wrote: > Hello, > > I would like some guidance in a way to filter data from an excel sheet > (.xlsx) > > I will be exporting an extensive table from a website with 400x20 infos. In > this sheet, I need to apply 3 or 4 filters and collect the amount of info > it shows then. Eg.: > > 1 - Export .xlsx from website Can you export to CSV instead? Its much easier to work with CSV files using the standard library than to use Excel sheets natively. There are Excel modules that you can download but CSV is standard functionality and Excel CSV format is the default. > 2 - Run python to filter > 2.1 - Filter by client A > 2.2 - Filter by task A > 2.3 - Filter by Person A Thats pretty meaningless without knowing the format of the tables. > 3 - Repeat filter for different clients, tasks and persons I'm not sure what you mean by "repeat filter" can you elaborate? > 4 - Collect the amount each person does inside each client. What do you mean "the amount"? Is that a column in the table or are you meaning a count of the number of entries by user? Without a view of the table format its hard to be any more specific. -- 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 Oct 26 11:11:21 2015 From: bgailer at gmail.com (Bob Gailer) Date: Mon, 26 Oct 2015 11:11:21 -0400 Subject: [Tutor] noob python question In-Reply-To: <1445814990929-5174789.post@n6.nabble.com> References: <1445814990929-5174789.post@n6.nabble.com> Message-ID: Welcome to the tutor list. In order for us to help you please post the following: Python version Operating system The code you are running To trace back you are getting The trace back will be several lines of references to various programs and line numbers Once we have that information then it becomes easy to help good luck On Oct 26, 2015 12:08 AM, "bob5487" wrote: > Howdy! > > Reading *Learn Python the Hard Way* Zed Shaw > > All good so far but got to Ex 42 dealing with classes... > > I get a TypeError: getattr(): attribute name must be a string when I run > the > program... > > I looked online, python reference manual 3rd edition, etc... > > I was wondering if anyone has experience with this book because I hit a > road > block > > > > > > -- > View this message in context: > http://python.6.x6.nabble.com/noob-python-question-tp5174789.html > Sent from the Python - tutor mailing list archive at Nabble.com. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From johnf at jfcomputer.com Mon Oct 26 13:20:02 2015 From: johnf at jfcomputer.com (john) Date: Mon, 26 Oct 2015 10:20:02 -0700 Subject: [Tutor] Python excel filter In-Reply-To: References: Message-ID: <562E60C2.8080207@jfcomputer.com> take a look at python-excel xlwt is what I use. BTW there are others Johnf On 10/26/2015 05:21 AM, Lucas Mascia wrote: > Hello, > > I would like some guidance in a way to filter data from an excel sheet > (.xlsx) > > I will be exporting an extensive table from a website with 400x20 infos. In > this sheet, I need to apply 3 or 4 filters and collect the amount of info > it shows then. Eg.: > > 1 - Export .xlsx from website > 2 - Run python to filter > 2.1 - Filter by client A > 2.2 - Filter by task A > 2.3 - Filter by Person A > 3 - Repeat filter for different clients, tasks and persons > 4 - Collect the amount each person does inside each client. > > > Please Help guide my through a starting poing > > Thank you, > > Lucas R. Mascia > > | VIEW MY | > > "It is not the strongest of the species that survives, nor the most > intelligent that survives. It is the one that is most adaptable to change." > - Darwin. > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor From badouglas at gmail.com Tue Oct 27 06:13:53 2015 From: badouglas at gmail.com (bruce) Date: Tue, 27 Oct 2015 06:13:53 -0400 Subject: [Tutor] Scraping Wikipedia Table (The retruned file is empty) In-Reply-To: References: Message-ID: my $0.02 for what it might be worth.. You have some people on the list who are straight out begineers who might be doing cut/copy/paste from 'bad code'. You have people coming from other languages.. and then you have some who are trying to 'get through' something, who aren't trying to be the dev!! And yeah, more time, could easily (in most cases) provide an answer, but sometimes, you just want to get a soln, and move on to the other 99 probs (no offense jay z!!) you guys have been a godsend at times! thanks - keep up the good fight/work. On Sun, Oct 25, 2015 at 9:56 PM, Alan Gauld wrote: > On 24/10/15 00:15, Mark Lawrence wrote: > >>> Looking more at the code... >>> >>> > for x in range(len(drama_actor)): >>> >>> This looks unusual... >> >> >> A better question IMHO is "where did you learn to write code like that >> in the first place", as I've seen so many examples of this that I cannot >> understand why people bother writing Python tutorials, as they clearly >> don't get read? >> > > I think its just a case of bad habits from other languages being > hard to shake off. If your language doesn't have a for-each operator then > its hard to wrap your brain around any other kind of for loop > than one based on indexes. > > It's a bit like dictionaries. They are super powerful but beginners coming > from other languages nearly always start out using > arrays(ie lists) and trying to "index" them by searching which > is hugely more complex, but it's what they are used too. > > JavaScript programmers tend to think the same about Python > programmers who insist on writing separate functions for > call backs rather than just embedding an anonymous function. > But Python programmers are used to brain dead lambdas with > a single expression so they don't tend to think about > embedding a full function. Familiarity with an idiom makes > it easier to stick with what you know than to try something new. > > -- > 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 richkappler at gmail.com Tue Oct 27 10:52:52 2015 From: richkappler at gmail.com (richard kappler) Date: Tue, 27 Oct 2015 10:52:52 -0400 Subject: [Tutor] socket communications and threading Message-ID: I'm having difficulty wrapping my arms around sockets and threading, not so much from a 10,000 foot/ network perspective, but from a low level perspective. In our production environment we have three machines that generate data and forward it over tcp to a computer that stores the data, parses it and sends it on to another computer over tcp for analytics. In our test environment we have simulated this by building three vm's. VM1 has a python script that sends raw data over tcp to VM2 which parses the data and sends it over tcp to VM3 upon which we are developing our analytics apps. Note that VM1 script reads from a .log file which is the actual output from three real machines, differentiated by a unique deviceID, and each line or 'event' in the .log file is read and sent over tcp with a 0.5 second delay between each read. VM2 has a python script that receives through a socket the raw data over tcp, parses it and sends it on through a socket over tcp to VM3. My lack of confusion arises for a couple reasons. 1. The data from the three different machines each gets it's own thread in production, so that would have to happen on 'VM2' as the 'VM1' are actually just microcontrollers out in production. From a socket and threading perspective, which would be considered the client and which the server, VM1 (the sender) or VM2 (the receiver)? 2. The process has worked mediocre at best thus far. When I developed the two python scripts (tunnelSim to send over socket and parser to rx and tx over socket) I started by just reading and writing to files so I could concentrate on the parsing bit. Once that was done and worked very well I added in sockets for data flow and commented out the read from and to files bits, and everything seemed to work fine, VM1 sent a number of 'lines', VM2 received the same number of 'lines', parsed them and, seemed to send them on. Some days analytics (VM3) got them all, some days it did not. Not sure where to look, and any thoughts on troubleshooting this would be helpful, but the main point of the entire email is question 1, threading. regards, Richard From alan.gauld at btinternet.com Tue Oct 27 13:44:36 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 27 Oct 2015 17:44:36 +0000 Subject: [Tutor] socket communications and threading In-Reply-To: References: Message-ID: On 27/10/15 14:52, richard kappler wrote: > In our test environment we have simulated this by building three vm's. VM1 > has a python script that sends raw data over tcp to VM2 which parses the > data and sends it over tcp to VM3 upon which we are developing our > analytics apps. >... > 1. The data from the three different machines each gets it's own thread in > production, so that would have to happen on 'VM2' as the 'VM1' are actually > just microcontrollers out in production. From a socket and threading > perspective, which would be considered the client and which the server, > VM1 (the sender) or VM2 (the receiver)? Client and server are about roles. The question is therefore which machine is requesting a service and which is providing it? Sounds like for the first transaction VM1 is asking VM2 to store the data, so VM1 is client, VM2 is server. However, for the analytics part, VM2 is asking for analysis and VM3 doing the work so VM2 is client in that transaction and VM3 the server. > 2. The process has worked mediocre at best thus far. When I developed the > two python scripts (tunnelSim to send over socket and parser to rx and tx > over socket) I started by just reading and writing to files so I could > concentrate on the parsing bit. Once that was done and worked very well I > added in sockets for data flow and commented out the read from and to files > bits, and everything seemed to work fine, VM1 sent a number of 'lines', VM2 > received the same number of 'lines', parsed them and, seemed to send them > on. Some days analytics (VM3) got them all, some days it did not. Not sure > where to look, and any thoughts on troubleshooting this would be helpful, > but the main point of the entire email is question 1, threading. Where is the threading question in #1? I only saw a question about client/server - which has nothing at all to do with threading? Slightly confused. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From richkappler at gmail.com Tue Oct 27 13:51:57 2015 From: richkappler at gmail.com (richard kappler) Date: Tue, 27 Oct 2015 13:51:57 -0400 Subject: [Tutor] socket communications and threading In-Reply-To: References: Message-ID: Sorry, thought it was clear. Each of the three different data generating machines (in the test env, the python script that sends the data with 3 different device names) goes over a different thread so the developers tell me. In production, those three machines are microcontrollers, not full blown computers. VM2 is a computer, so that must be where the threads 'occur' (again, I don't understand this well) but in the examples I read, it was about which was server and which was client, hence the connection between client/server and threading. With your explanation I am off to re-read the tutorials and examples, thank you. regards, Richard On Tue, Oct 27, 2015 at 1:44 PM, Alan Gauld wrote: > On 27/10/15 14:52, richard kappler wrote: > > In our test environment we have simulated this by building three vm's. VM1 >> has a python script that sends raw data over tcp to VM2 which parses the >> data and sends it over tcp to VM3 upon which we are developing our >> analytics apps. >> ... >> > > 1. The data from the three different machines each gets it's own thread in >> production, so that would have to happen on 'VM2' as the 'VM1' are >> actually >> just microcontrollers out in production. From a socket and threading >> perspective, which would be considered the client and which the server, >> VM1 (the sender) or VM2 (the receiver)? >> > > Client and server are about roles. The question is therefore > which machine is requesting a service and which is providing > it? Sounds like for the first transaction VM1 is asking VM2 to > store the data, so VM1 is client, VM2 is server. > > However, for the analytics part, VM2 is asking for analysis and > VM3 doing the work so VM2 is client in that transaction and VM3 > the server. > > 2. The process has worked mediocre at best thus far. When I developed the >> two python scripts (tunnelSim to send over socket and parser to rx and tx >> over socket) I started by just reading and writing to files so I could >> concentrate on the parsing bit. Once that was done and worked very well I >> added in sockets for data flow and commented out the read from and to >> files >> bits, and everything seemed to work fine, VM1 sent a number of 'lines', >> VM2 >> received the same number of 'lines', parsed them and, seemed to send them >> on. Some days analytics (VM3) got them all, some days it did not. Not sure >> where to look, and any thoughts on troubleshooting this would be helpful, >> but the main point of the entire email is question 1, threading. >> > > Where is the threading question in #1? I only saw a question about > client/server - which has nothing at all to do with threading? > > Slightly confused. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- All internal models of the world are approximate. ~ Sebastian Thrun From robertvstepp at gmail.com Tue Oct 27 16:20:56 2015 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 27 Oct 2015 15:20:56 -0500 Subject: [Tutor] Are there any Python-based GUI builders for tkinter Message-ID: I have a friend at work and he is trying to develop GUI applications in Python, but he does not want to hand-code them. Are there any commercial or non-commercial products that would do this for him? He tried his own online search but was unsuccessful. His OS is Mac OS 10.10 and is using Python 3.5. TIA! -- boB From jarod_v6 at libero.it Tue Oct 27 17:32:51 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Tue, 27 Oct 2015 22:32:51 +0100 (CET) Subject: [Tutor] How to parse large files Message-ID: <209738453.4803691445981571340.JavaMail.httpd@webmail-10.iol.local> Hi! I want to reads two files and create simple dictionary. Input file contain more than 10000 rows diz5 = {} with open("tmp1.txt") as p: for i in p: lines = i.rstrip("\n").split("\t") diz5.setdefault(lines[0],set()).add(lines[1]) diz3 = {} with open("tmp2.txt") as p: for i in p: lines = i.rstrip("\n").split("\t") diz3.setdefault(lines[0],set()).add(lines[1]) how can manage better this reading and writing? thanks so much From jarod_v6 at libero.it Tue Oct 27 17:37:11 2015 From: jarod_v6 at libero.it (jarod_v6 at libero.it) Date: Tue, 27 Oct 2015 22:37:11 +0100 (CET) Subject: [Tutor] R: Re: Create complex dictionary :p: Message-ID: <605183756.4804361445981831148.JavaMail.httpd@webmail-10.iol.local> Sorry, I just realize my question are wrong: I want to knowhow to do dictionary of dictionary in most python way: diz = { "A"={"e"=2,"s"=10},"B"={"e"=20,"s"=7}} So I have some keys (A,B) is correlate with a new dictionary where I have other key I want to use. I want to extract for each key the "e" value. thanks From breamoreboy at yahoo.co.uk Tue Oct 27 18:24:04 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 27 Oct 2015 22:24:04 +0000 Subject: [Tutor] How to parse large files In-Reply-To: <209738453.4803691445981571340.JavaMail.httpd@webmail-10.iol.local> References: <209738453.4803691445981571340.JavaMail.httpd@webmail-10.iol.local> Message-ID: On 27/10/2015 21:32, jarod_v6--- via Tutor wrote: > Hi! > I want to reads two files and create simple dictionary. Input file contain more than 10000 rows > > > diz5 = {} > with open("tmp1.txt") as p: > for i in p: > lines = i.rstrip("\n").split("\t") > diz5.setdefault(lines[0],set()).add(lines[1]) > > diz3 = {} > with open("tmp2.txt") as p: > for i in p: > lines = i.rstrip("\n").split("\t") > diz3.setdefault(lines[0],set()).add(lines[1]) > > how can manage better this reading and writing? > thanks so much > https://docs.python.org/3/library/csv.html https://docs.python.org/3/library/csv.html#csv.DictReader https://docs.python.org/3/library/csv.html#csv.DictWriter https://docs.python.org/3/library/csv.html#csv.excel_tab -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From breamoreboy at yahoo.co.uk Tue Oct 27 18:38:47 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Tue, 27 Oct 2015 22:38:47 +0000 Subject: [Tutor] R: Re: Create complex dictionary :p: In-Reply-To: <605183756.4804361445981831148.JavaMail.httpd@webmail-10.iol.local> References: <605183756.4804361445981831148.JavaMail.httpd@webmail-10.iol.local> Message-ID: On 27/10/2015 21:37, jarod_v6--- via Tutor wrote: > Sorry, > I just realize my question are wrong: I want to knowhow to do dictionary of > dictionary in most python way: > > diz = { "A"={"e"=2,"s"=10},"B"={"e"=20,"s"=7}} > > So I have some keys (A,B) is correlate with a new dictionary where I have > other key I want to use. I want to extract for each key the "e" value. > thanks > So having sorted out the dict syntax how about. >>> diz = {"A":{"e":2,"s":10},"B":{"e":20,"s":7}} >>> es = {} >>> for k,v in diz.items(): ... es[k] = v["e"] ... >>> es {'B': 20, 'A': 2} -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From steve at pearwood.info Tue Oct 27 18:51:21 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 28 Oct 2015 09:51:21 +1100 Subject: [Tutor] R: Re: Create complex dictionary :p: In-Reply-To: <605183756.4804361445981831148.JavaMail.httpd@webmail-10.iol.local> References: <605183756.4804361445981831148.JavaMail.httpd@webmail-10.iol.local> Message-ID: <20151027225121.GY3813@ando.pearwood.info> On Tue, Oct 27, 2015 at 10:37:11PM +0100, jarod_v6--- via Tutor wrote: > Sorry, > I just realize my question are wrong: I want to knowhow to do dictionary of > dictionary in most python way: > > diz = { "A"={"e"=2,"s"=10},"B"={"e"=20,"s"=7}} Like that, except you need to use colons: diz = {"A": {"e": 2, "s": 10}, "B": {"e": 20, "s": 7}, "C": {"a": 1, "b": 2, "c": 3}, } If your dictionary can be calculated, you could write this: diz = dict((key, dict((k,v) for (k,v) in zip("es", range(2)))) for key in "ABCD") print(diz) => prints this nested dict: {'B': {'s': 1, 'e': 0}, 'A': {'s': 1, 'e': 0}, 'D': {'s': 1, 'e': 0}, 'C': {'s': 1, 'e': 0}} but that rapidly gets complicated and hard to read! A better idea might be something like this: innerdict = {"e": 0, "s": 1} diz = dict((key, innerdict.copy()) for key in "ABCD") > So I have some keys (A,B) is correlate with a new dictionary where I have > other key I want to use. I want to extract for each key the "e" value. > thanks # Method one: for key in diz: value = diz[key]["e"] print("The key is %s, the value is %s" % (key, value)) # Method two: for key, subdict in diz.items(): value = subdict["e"] print("The key is %s, the value is %s" % (key, value)) # Method three: for subdict in diz.values(): value = subdict["e"] print("The key is unknown, the value is %s" % value) -- Steve From steve at pearwood.info Tue Oct 27 18:57:23 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 28 Oct 2015 09:57:23 +1100 Subject: [Tutor] How to parse large files In-Reply-To: <209738453.4803691445981571340.JavaMail.httpd@webmail-10.iol.local> References: <209738453.4803691445981571340.JavaMail.httpd@webmail-10.iol.local> Message-ID: <20151027225723.GZ3813@ando.pearwood.info> On Tue, Oct 27, 2015 at 10:32:51PM +0100, jarod_v6--- via Tutor wrote: > Hi! > I want to reads two files and create simple dictionary. Input file contain more than 10000 rows Since you are talking about a tab-delimited CSV file, you should use the csv module: https://pymotw.com/2/csv/ https://docs.python.org/2/library/csv.html Unfortunately the version 2 csv module doesn't deal with non-ASCII characters very well, but the Python 3 version does: https://docs.python.org/3/library/csv.html -- Steve From alan.gauld at btinternet.com Tue Oct 27 19:58:14 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Tue, 27 Oct 2015 23:58:14 +0000 Subject: [Tutor] socket communications and threading In-Reply-To: References: Message-ID: <56300F96.9090503@btinternet.com> On 27/10/15 17:51, richard kappler wrote: > Sorry, thought it was clear. Each of the three different data > generating machines > (in the test env, the python script that sends the data with 3 > different device names) > goes over a different thread so the developers tell me. OK, You need to get the concepts clear. Threads are about parallel processing. They occur on a processor and have nothing to do with communications. They are one of several mechanisms that enable multiple tasks to run in parallel on a single computer. Each thread is a sub-process of the parent process. Its common, but not necessary, for the threads to all be clones of each other, but they could equally be multiple different types of process. Sockets are simply communications channels. They connect two processes, usually over a network but not necessarily. They have no direct relationship to threads. It is, however, very common to have different threads (different instances of a process) handle each communication channel, but it's by no means necessary. > in the examples I read, it was about which was server and which was > client, As I said, client/server is about the nature of the communications between two processes (which are often on two different computers but don't have to be). The nature of the client and server processes is completely open, it could involve communicating over sockets, but it might not. It could involve multiple threads, it might not. They key thing that defines the relationship is that clients send requests to the server which sends responses back. The server never sends requests to the client (if it did it would be peer to peer not client/server). The server may send unsolicited events (notifications) to its clients (either broadcast to all or targeted at one) but it does not expect a response. All of these concepts are separate and not dependant on each other. You could have multiple client threads as well as multiple server threads, or no threads at all. It could all run on a single computer, with or without sockets. In particular, it's common today to use higher level comms mechanisms such as http with JSON/XMLRPC/SOAP. Sockets are used under the covers but the programmer doesn't need to know. So to summarize what I think is going on in your case, you have: VM1 A single threaded client process running on a micro-controller sending requests to a remote server (VM2) Question: is there really only one client controller or is it actually 3, one per logged machine? How do the logged machines communicate to the controller(s)? VM2 A multi threaded server process running on a conventional computer (a PC? Mac? which OS?) It receives messages from the client(s?) and allocates these messages to one of three threads(sub processes) depending on message source. The server then acts as a client process and sends requests to another micro controller acting as a server(VM3). Questions: Are the messages to VM3 sent from the individual threads? Do they all go down a single socket connection? Or is there a top level VM2 process that forwards the messages to VM3? Or is there in fact a 4th VM2 thread/process relaying the messages to VM3? (perhaps triggered from a database? or as a polling process). VM3 A single threaded server process that receives messages and analyses their content. I don't know what it does with the result... In each case the messaging is done over raw sockets. Is that a fair summary? PS. You might find it helpful to look at my tutorial sections on inter-process comms and network programming. It covers client-server on a single machine then using sockets to extend it to two machines (but uses an alternative, simpler form of multi-processing to threads). Its in Python 2 but should convert easily to Python 3. http://www.alan-g.me.uk/tutor/tutipc.htm But converting the model to threads would not be difficult (and indeed was planned for the, as yet unwritten, topic on parallel processing!) -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Tue Oct 27 20:06:52 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 28 Oct 2015 00:06:52 +0000 Subject: [Tutor] Are there any Python-based GUI builders for tkinter In-Reply-To: References: Message-ID: On 27/10/15 20:20, boB Stepp wrote: > I have a friend at work and he is trying to develop GUI applications > in Python, but he does not want to hand-code them. Are there any > commercial or non-commercial products that would do this for him? He > tried his own online search but was unsuccessful. There are a few SpecTcl is one that works for Tcl and there was a version of SpecTcl for python. There are GUI builders for other toolkits too. Dabo (wxPython at heart but adds its own widgets on top) is the only one I've found that works well (at least when I tried it). But frankly they are generally not very good, or reliable (crashes/lockups etc) especially if you are used to something like VB. Its much easier and faster to just use text once you get used to it. Others may have had more luck but I tried about 5 or 6 tools and they all sucked! -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Tue Oct 27 20:16:24 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 28 Oct 2015 00:16:24 +0000 Subject: [Tutor] socket communications and threading In-Reply-To: <56300F96.9090503@btinternet.com> References: <56300F96.9090503@btinternet.com> Message-ID: On 27/10/15 23:58, Alan Gauld wrote: > that enable multiple tasks to run in parallel on a single computer. Each > thread is a sub-process of the parent process. I should add that this is a bit of a simplification because threading varies in implementation depending on OS and language. Threads are conceptual subprocesses but may in fact be a part of the parent process from the OS perspective. In general threads are more efficient (less memory, faster to start/stop) than true sub-processes but it all depends on the implementation. Python threading in particular is not especially efficient. Threading is notoriously tricky to get right although the simpler you keep the design (ideally, stateless processing, with no shared data) the easier it is. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From dyoo at hashcollision.org Tue Oct 27 22:32:06 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 27 Oct 2015 19:32:06 -0700 Subject: [Tutor] How to parse large files In-Reply-To: <209738453.4803691445981571340.JavaMail.httpd@webmail-10.iol.local> References: <209738453.4803691445981571340.JavaMail.httpd@webmail-10.iol.local> Message-ID: On Tue, Oct 27, 2015 at 2:32 PM, jarod_v6--- via Tutor wrote: > Hi! > I want to reads two files and create simple dictionary. Input file contain more than 10000 rows > > diz5 = {} > with open("tmp1.txt") as p: > for i in p: > lines = i.rstrip("\n").split("\t") > diz5.setdefault(lines[0],set()).add(lines[1]) > > diz3 = {} > with open("tmp2.txt") as p: > for i in p: > lines = i.rstrip("\n").split("\t") > diz3.setdefault(lines[0],set()).add(lines[1]) 10000 rows today is not a lot of data, since typical computer memories have grown quite a bit. I get the feeling your program should be able to handle this all in-memory. But let's assume, for the moment, that you do need to deal with a lot of data, where you can't hold the whole thing in memory. Ideally, you'd like to have access to its contents in a key/value store, because that feels most like a Python dict. If that's the case, then what you're looking for is a on on-disk database. There are several out there; one that comes standard in Python 3 is the "dbm" module: https://docs.python.org/3.5/library/dbm.html Instead of doing: diz5 = {} ... we'd do something like this: with diz5 = dbm.open('diz5, 'c'): ... And otherwise, your code will look very similar! This dictionary-like object will store its data on disk, rather than in-memory, so that it can grow fairly large. The other nice thing is that you can do the dbm creation up front. If you run your program again, you might add a bit of logic to *reuse* the dbm that's already on disk, so that you don't have to process your input files all over again. Databases, too, have capacity limits, but you're unlikely to hit them unless you're really doing something hefty. And that's out of scope for tutor at python.org. :P From dyoo at hashcollision.org Tue Oct 27 22:34:30 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Tue, 27 Oct 2015 19:34:30 -0700 Subject: [Tutor] How to parse large files In-Reply-To: References: <209738453.4803691445981571340.JavaMail.httpd@webmail-10.iol.local> Message-ID: > Instead of doing: > > diz5 = {} > ... > > we'd do something like this: > > with diz5 = dbm.open('diz5, 'c'): Sorry, I'm getting my syntax completely wrong here. My apologies. This should be: with dbm.open('diz5', 'c') as diz5: ... Apologies: I just got back from work and my brain is mush. From lac at openend.se Wed Oct 28 04:39:55 2015 From: lac at openend.se (Laura Creighton) Date: Wed, 28 Oct 2015 09:39:55 +0100 Subject: [Tutor] Are there any Python-based GUI builders for tkinter In-Reply-To: References: Message-ID: <201510280839.t9S8dto9026889@fido.openend.se> In a message of Tue, 27 Oct 2015 15:20:56 -0500, boB Stepp writes: >I have a friend at work and he is trying to develop GUI applications >in Python, but he does not want to hand-code them. Are there any >commercial or non-commercial products that would do this for him? He >tried his own online search but was unsuccessful. > >His OS is Mac OS 10.10 and is using Python 3.5. > >TIA! > >-- >boB check out QtDesigner http://doc.qt.io/qt-5/qtdesigner-manual.html or QtCreator http://www.qt.io/ide/ if you want the whole process to happen inside an IDE. https://wiki.python.org/moin/PyQt/Creating_GUI_Applications_with_PyQt_and_Qt_Designer may be useful as well, though its a little old by now. Laura From __peter__ at web.de Wed Oct 28 05:02:17 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 28 Oct 2015 10:02:17 +0100 Subject: [Tutor] How to parse large files References: <209738453.4803691445981571340.JavaMail.httpd@webmail-10.iol.local> Message-ID: Danny Yoo wrote: > There are several out there; one that comes standard in Python 3 is > the "dbm" module: > > https://docs.python.org/3.5/library/dbm.html > > Instead of doing: > > diz5 = {} > ... > > we'd do something like this: > > with diz5 = dbm.open('diz5, 'c'): > ... > > And otherwise, your code will look very similar! This dictionary-like > object will store its data on disk, rather than in-memory, so that it > can grow fairly large. The other nice thing is that you can do the > dbm creation up front. If you run your program again, you might add a > bit of logic to *reuse* the dbm that's already on disk, so that you > don't have to process your input files all over again. dbm operates on byte strings for both keys and values, so there are a few changes. Fortunately there's a wrapper around dbm called shelve that uses string keys and allows objects that can be pickled as values: https://docs.python.org/dev/library/shelve.html With that your code may become with shelve.open("diz5") as db: with open("tmp1.txt") as instream: for line in instream: assert line.count("\t") == 1 key, _tab, value = line.rstrip("\n").partition("\t") values = db.get(key) or set() values.add(value) db[key] = values Note that while shelve has a setdefault() method it will only work as expected when you set writeback=True which in turn may require arbitrary amounts of memory. From hunter.t.joz at gmail.com Tue Oct 27 21:04:45 2015 From: hunter.t.joz at gmail.com (Hunter Jozwiak) Date: Tue, 27 Oct 2015 21:04:45 -0400 Subject: [Tutor] Demystification of Lambda Functions Message-ID: <007901d1111c$a31d54e0$e957fea0$@gmail.com> Hello, I am not sure exactly why there would be a practical use for a lambda function, other than the fact that you can make one-liner functions that take parameters in to a variable. Or at least that is how things look when they are written. Can I have some demystification? Thanks, Hunter From lac at openend.se Wed Oct 28 06:01:50 2015 From: lac at openend.se (Laura Creighton) Date: Wed, 28 Oct 2015 11:01:50 +0100 Subject: [Tutor] Demystification of Lambda Functions In-Reply-To: <007901d1111c$a31d54e0$e957fea0$@gmail.com> References: <007901d1111c$a31d54e0$e957fea0$@gmail.com> Message-ID: <201510281001.t9SA1ouL001115@fido.openend.se> In a message of Tue, 27 Oct 2015 21:04:45 -0400, "Hunter Jozwiak" writes: >Hello, > > > >I am not sure exactly why there would be a practical use for a lambda >function, other than the fact that you can make one-liner functions that >take parameters in to a variable. Or at least that is how things look when >they are written. Can I have some demystification? > > > >Thanks, >Hunter Practically the only time I use them is to code callbacks in Tkinter functions. see: https://pythonconquerstheuniverse.wordpress.com/2011/08/29/lambda_tutorial/ for why it is useful. Laura From alan.gauld at btinternet.com Wed Oct 28 06:23:56 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 28 Oct 2015 10:23:56 +0000 Subject: [Tutor] Demystification of Lambda Functions In-Reply-To: <007901d1111c$a31d54e0$e957fea0$@gmail.com> References: <007901d1111c$a31d54e0$e957fea0$@gmail.com> Message-ID: On 28/10/15 01:04, Hunter Jozwiak wrote: > I am not sure exactly why there would be a practical use for a lambda > function, other than the fact that you can make one-liner functions that > take parameters in to a variable. Or at least that is how things look when > they are written. Can I have some demystification? One thing to remember when dealing with Python is that it started out as a teaching language. That is, a language used to teach computer science and programming. As such, many of its features are designed to be easy to use. Others are there to demonstrate computer science concepts. One of those concepts is the idea of functional programming, where functions are treated like data objects. Many of those ideas in turn come from Church's "Lambda Calculus" and the idea of a lambda being an executable object. In other languages lambdas are much more powerful but in Python they were limited to a single expression so their full power is harder to see. If you look at JavaScript (or Lisp) it uses the concepts behind Lambda much more and the use of anonymous functions is almost endemic in modern Javascript libraries like JQuery, Angular, Node and so on. In Python we are forced to define complex functions as separate entities, so the JScript style cannot be used. So what are we left with in Python? 1) lambda makes programmers aware of the term 'lambda' and that it is somehow significant in computer science. (Just like with you, it stimulates curiosity). 2) lambdas are useful for teaching that def f(x): return expression(x) is the same as writing f = lambda x: expression(x) where f is just a variable name like any other. (Whereas the def syntax tends to suggest that the f name is somehow different to other names, that it has some kind of superpowers just because its a function name, when in fact it doesn't. Its just a name.) 3) lambdas allow us to create short anonymous functions in call backs or to wrap longer generic functions with specific values. 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 anshu.kumar726 at gmail.com Wed Oct 28 05:34:28 2015 From: anshu.kumar726 at gmail.com (Anshu Kumar) Date: Wed, 28 Oct 2015 15:04:28 +0530 Subject: [Tutor] Demystification of Lambda Functions In-Reply-To: <007901d1111c$a31d54e0$e957fea0$@gmail.com> References: <007901d1111c$a31d54e0$e957fea0$@gmail.com> Message-ID: Hi, Lambda or anonymous function is core of functional programming which was not in java. With lambda you can pass not just define an anonymous function but can pass them to other functions which really makes life easier. You would like to read http://www.python-course.eu/lambda.php http://www.python-course.eu/lambda.php Thanks, Anshu On Wed, Oct 28, 2015 at 6:34 AM, Hunter Jozwiak wrote: > Hello, > > > > I am not sure exactly why there would be a practical use for a lambda > function, other than the fact that you can make one-liner functions that > take parameters in to a variable. Or at least that is how things look when > they are written. Can I have some demystification? > > > > Thanks, > > > > Hunter > > _______________________________________________ > Tutor maillist - Tutor at python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > From steve at pearwood.info Wed Oct 28 07:36:49 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Wed, 28 Oct 2015 22:36:49 +1100 Subject: [Tutor] Demystification of Lambda Functions In-Reply-To: <007901d1111c$a31d54e0$e957fea0$@gmail.com> References: <007901d1111c$a31d54e0$e957fea0$@gmail.com> Message-ID: <20151028113648.GA10946@ando.pearwood.info> On Tue, Oct 27, 2015 at 09:04:45PM -0400, Hunter Jozwiak wrote: > Hello, > > I am not sure exactly why there would be a practical use for a lambda > function, other than the fact that you can make one-liner functions that > take parameters in to a variable. Or at least that is how things look when > they are written. Can I have some demystification? To understand why lambda is useful will require a bit of background. So let me start at the beginning. The first thing you have to understand is that in modern languages like Python, functions are not just things that operate on values, but they are values themselves. So you can have a function which returns a new function as its result. Here is a simple example: py> def make_adder(n): ... def adder(x): ... return x + n ... return adder ... py> add_one = make_adder(1) py> add_one(100) 101 py> add_five = make_adder(5) py> add_five(100) 105 "make_adder" is a function which takes an argument, n, and returns a new function which takes one argument and returns that value plus the earlier value "n". So make_adder(1) builds a function that adds 1 to its argument, and make_adder(2) builds a function that adds 5 to its argument. Functions can not merely return functions, they can also take them as an argument. Here's a simple example: py> def add(a, b): # Function that adds two values. ... return a + b ... py> def times(a, b): # Function that multiplies two values. ... return a*b ... py> def builder(func): ... def op3(x): ... return func(x, 3) ... return op3 ... py> add_three = builder(add) py> add_three(5) 8 py> times_three = builder(times) py> times_three(5) 15 Now, those two examples themselves aren't terribly useful, it isn't very often that you need a whole bunch of functions: add_one add_two add_three etc. But the ability to manipulate functions as arguments itself is useful. For example, suppose you have a set of strings, and you need to find out how long they all are: py> strings = ["cat", "dog", "cheese", "aardvark", "elephant", "hamburger"] py> lengths = [] py> for s in strings: ... lengths.append(len(s)) ... py> print lengths [3, 3, 6, 8, 8, 9] Having to build up a list yourself is a bit tedious, but there's another way: py> print map(len, strings) # Python 2 version. [3, 3, 6, 8, 8, 9] The "map" function takes a function (in this case, len) and applies it to each item in strings, consolidating the results. The Python 3 version is a little different, but the basic concept remains the same. Suppose we had a list of numbers, and we wanted to create a new list with each number doubled and then one added. We could do this: py> def double_and_add_one(x): ... return 2*x + 1 ... py> map(double_and_add_one, [2, 3, 4, 5]) [5, 7, 9, 11] but it seems a bit wasteful to have that function "double_and_add_one" floating around in our program after we've used it, doing nothing useful. It has a name and everything. Python lets us create an unnamed function, right there in the expression where it is being used. Once used, the interpreter can delete the function and reclaim its memory. To do this, we use lambda: py> map(lambda x: 2*x+1, [2, 3, 4, 5]) [5, 7, 9, 11] If you have a function that looks like this: def FUNCTION(args): return EXPRESSION that can be written using the lambda syntax: lambda args: EXPRESSION dropped right in the place where you are planning to use it, instead of having to pre-define it using "def". That makes lambda especially convenient for callback functions. For example, many GUI toolkits let you set callbacks. Suppose you create a button using some toolkit, like this, say: save_button = Button("save", style="round") What does the button do? So far, nothing: you can click on it, and nothing happens. To give the button an action, you have to give it a callback function. A callback is a function that the button will call when you click on it: def save(thebtn): # whatever code you need to save the document save_button = Button("save", style="round", callback=save) Sometimes callbacks are particularly short and simple. Suppose you are programming a calculator, and you have ten buttons 0...9 which all do precisely the same thing: they add their own name to the calculator display: for num in range(0, 10): btn = Button(str(num), style="rectangle", callback = lambda thebtn: display.add(thebtn.name) ) Much better than having to pre-define ten functions and add them to each of the buttons. These functions are called "anonymous functions", because unlike functions created with "def", they don't have a name. Well, technically they do, but they're all the same name: py> (lambda x: x+1).__name__ '' which is only used for display, say, if there is an error. What makes anonymous functions especially useful in languages other than Python is that they are created at runtime, not compile-time, so they can include information that is only known when the program runs. They are also expressions, not statements, so you can use them wherever you might use some other expression: things = [123, "something", lambda x: x+1, {}, None] You can't imbed a "def" inside a list, you have to define the function first (giving it a name), then put it in the list: things = [123, "something"] def add_one(x): return x + 1 things.append(add_one) things.append({}) things.append(None) So lambda is useful for writing small, simple, use-once and throw-away functions. There are two things to remember about lambda: - Functions that you create with lambda are exactly the same as those you create with def (apart from the lack of a name). def and lambda don't create two different kinds of function, they are the same kind of function. Only the syntax (and name) is different. - lambda syntax is restricted to a single expression. So you can't write: lambda x: y = [] y.append(x) return y that will give a syntax error. Any further questions, feel free to ask. -- Steve From soweto at gmail.com Wed Oct 28 11:09:59 2015 From: soweto at gmail.com (Vusa Moyo) Date: Wed, 28 Oct 2015 17:09:59 +0200 Subject: [Tutor] Messy - Very Messy string manipulation. Message-ID: Hi Guys, I've written a script to remove vowels from a string/sentence. the while loop I'm using below is to take care of duplicate vowels found in a sentence, ie anti_vowel('The cow moos louder than the frog') It works, but obviously its messy and n00by. Any suggestions on how I can write this code better? ---- def anti_vowel(text): vowel = ['a', 'e', 'i', 'o', 'u'] VOWEL = ['A', 'E', 'I', 'O', 'U'] manip = [] for i in text: manip.append(i) fufu = 0 # while fufu < 16: for x in vowel: if x in manip: manip.remove(x) for y in VOWEL: if y in manip: manip.remove(y) fufu = fufu + 2 strong = ''.join(manip) return strong ---- Thanks - Vusa From Steve.Flynn at capita.co.uk Wed Oct 28 10:48:05 2015 From: Steve.Flynn at capita.co.uk (Flynn, Stephen (L & P - IT)) Date: Wed, 28 Oct 2015 14:48:05 +0000 Subject: [Tutor] How do I (idiomatically) determine when I'm looking at the last entry in a list? Message-ID: <5C71288A643C6249B50BC6B27CB3A14C020412F7@CAPPRWMMBX23.central.ad.capita.co.uk> Afternoon, Python 3. I'm iterating through a list and I'd like to know when I'm at the end of the said list, so I can do something different. For example list_of_things = ['some', 'special', 'things'] for each_entry in list_of_things: print(each_entry) if each_entry == list_of_things[-1]: # do something special to last entry ...etc Is this the idiomatic way to detect you're at the last entry in a list as you iterate through it? For context, I'm working my way through a (csv) file which describes some database tables. I'm building the Oracle DDL to create that table as I go. When I find myself building the last column, I want to finish the definition with a ");" rather than the usual "," which occurs at the end of all other column definitions... e.g. CREATE TABLE wibble ( Col1 CHAR(2), Col2 NUMBER(5,2), ); Regards, Steve. This email is security checked and subject to the disclaimer on web-page: http://www.capita.co.uk/email-disclaimer.aspx From lac at openend.se Wed Oct 28 11:57:20 2015 From: lac at openend.se (Laura Creighton) Date: Wed, 28 Oct 2015 16:57:20 +0100 Subject: [Tutor] Are there any Python-based GUI builders for tkinter (fwd) Message-ID: <201510281557.t9SFvKTO028395@fido.openend.se> Ooops, didn't send this to the list. sorry. Laura ------- Forwarded Message >Laura, > >I checked out QtCreator but see zero sign of it supporting python - even tried a search and the only hit was a job opening. Am I missing something? > > >Jon Paris The Qt Creator announcment for the 2.8.0 release says: An editor specific for Python was added, with highlighting and indentation, and a Python class wizard http://blog.qt.io/blog/2013/07/11/qt-creator-2-8-0-released/ so I thought that meant it supported Python. Seems the support is rather rough around the edges, but I found some good information here: http://stackoverflow.com/questions/24100602/developing-python-applications-in-qt-creator Laura ------- End of Forwarded Message From zachary.ware+pytut at gmail.com Wed Oct 28 12:09:24 2015 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Wed, 28 Oct 2015 11:09:24 -0500 Subject: [Tutor] Messy - Very Messy string manipulation. In-Reply-To: References: Message-ID: On Wed, Oct 28, 2015 at 10:09 AM, Vusa Moyo wrote: > Hi Guys, > > I've written a script to remove vowels from a string/sentence. > > the while loop I'm using below is to take care of duplicate vowels found in > a sentence, ie > > anti_vowel('The cow moos louder than the frog') > > It works, but obviously its messy and n00by. Any suggestions on how I can > write this code better? First off, the code that works (by "works" I mean "passes its tests") is far better than the code that doesn't, no matter what form that code takes. That said, there are several tricks you can use to significantly shorten your function here. > def anti_vowel(text): I'd rather name this "remove_vowels", since that's what it *does* rather than what it *is* is an English sense. > vowel = ['a', 'e', 'i', 'o', 'u'] > VOWEL = ['A', 'E', 'I', 'O', 'U'] Strings can be thought of as tuples optimized for characters, with some special methods. Tuples, in turn, can be thought of as immutable lists. So the above can be shortened to: vowel = 'aeiou' VOWEL = 'AEIOU' Using one of those special methods I mentioned: vowel = 'aeiou' VOWEL = vowel.upper() But do we really need two separate vowel containers? vowels = 'aeiou' all_vowels = vowels + vowels.upper() Or to save a name, and some typing: vowels = 'aeiou' vowels += vowels.upper() > manip = [] > > for i in text: > manip.append(i) Any time you have the pattern "create an empty list, then append to it in a for loop", think "comprehension". The above could be shortened to: manip = [i for i in text] Or, since the list constructor takes an iterable argument and strings give characters upon iteration: manip = list(text) But we don't really need manip at all, as I'll show further down. > fufu = 0 > # > while fufu < 16: This is a fairly weird way to spell "loop 8 times", if I'm honest :). A more idiomatic approach would be to get rid of 'fufu' and do this instead: for each in range(8): Which loops 8 times and assigns the number of the loop (0-7) to the name 'each' each time around. 'each' could be any valid identifier ('_' is commonly used for this), 'each' just makes sense reading the line as English. > for x in vowel: > if x in manip: > manip.remove(x) > > for y in VOWEL: > if y in manip: > manip.remove(y) Above, we combined 'vowel' and 'VOWEL' into 'vowels', so these can be shortened into a single loop by removing the second loop and changing the first to iterate over 'vowels' instead of 'vowel'. But instead of removing values from a list we just built, it's easier to build the list without those values in the first place, see below. > fufu = fufu + 2 This line goes away with the change from 'while' to 'for each in range'. > strong = ''.join(manip) > return strong I suspect this was meant to be 'string' :). Anyway, 'return' can return any expression not just a name, so this could be just: return ''.join(manip) So, what was I talking about with not needing 'manip' and building the list without the values in the first place? Combining some other stuff mentioned above, we can build a list of the characters of the given text, minus vowels, using a comprehension: list_of_chars_without_vowels = [c for c in text if c not in vowels] To better understand what's going on here, you can "unroll" the comprehension by initializing the name to an empty list, then moving the initial expression (the "c" in "c for ...") to an append call all the way inside: list_of_chars_without_vowels = [] for c in text: if c not in vowels: list_of_chars_without_vowels.append(c) 'list_of_chars_without_vowels' is then in the same state your 'manip' was in after the loops, so the loops go away entirely. 'list_of_chars_without_vowels' is an unwieldy name, but we don't actually need to name it: return ''.join([c for c in text if c not in vowels]) And one final optimization (which in this case is more of a finger optimization than a performance optimization), we can drop the square brackets to turn the list comprehension into a generator expression: return ''.join(c for c in text if c not in vowels) The difference between the two above statements is that the first calculates the entire list of characters, then passes it to ''.join(), which iterates through the list to create the final string, while the second creates a generator and passes it to ''.join(), and the generator calculates and yields the next character each time ''.join() calls next() on it. To put everything together, here's my final version, with a docstring, a punny Easter egg, and a very simplistic test that is not adequate testing: import random def remove_vowels(text): """Remove all vowels from 'text' and return the result.""" vowels = 'aeiou' + random.choice(['y', '']) # "and sometimes y" vowels += vowels.upper() return ''.join(c for c in text if c not in vowels assert remove_vowels('Did It work? Looks like.') == 'Dd t wrk? Lks Lke.' Hoping I may have taught you something, -- Zach From zachary.ware+pytut at gmail.com Wed Oct 28 12:11:18 2015 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Wed, 28 Oct 2015 11:11:18 -0500 Subject: [Tutor] Messy - Very Messy string manipulation. In-Reply-To: References: Message-ID: On Wed, Oct 28, 2015 at 11:09 AM, Zachary Ware wrote: > assert remove_vowels('Did It work? Looks like.') == 'Dd t wrk? Lks Lke.' Of course I typo'd here (that's what you get for not testing!): there should be no final 'e' and the last 'L' should be lower-case. assert remove_vowels('Did It work? Looks like.') == 'Dd t wrk? Lks lk.' -- Zach From __peter__ at web.de Wed Oct 28 12:27:46 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 28 Oct 2015 17:27:46 +0100 Subject: [Tutor] How do I (idiomatically) determine when I'm looking at the last entry in a list? References: <5C71288A643C6249B50BC6B27CB3A14C020412F7@CAPPRWMMBX23.central.ad.capita.co.uk> Message-ID: Flynn, Stephen (L & P - IT) wrote: > Afternoon, > > Python 3. > > I'm iterating through a list and I'd like to know when I'm at > the end of the said list, so I can do something different. For example > > list_of_things = ['some', 'special', 'things'] > for each_entry in list_of_things: > print(each_entry) > if each_entry == list_of_things[-1]: # do something special to > last entry > ...etc > > > Is this the idiomatic way to detect you're at the last entry in a list > as you iterate through it? If the list is small you can slice it: assert items for item in things[:-1]: print(item, ",", sep="") print(items[-1]) I have written a generator similar to >>> def g(items): ... items = iter(items) ... try: ... prev = next(items) ... except StopIteration: ... return ... for item in items: ... yield False, prev ... prev = item ... yield True, prev ... >>> for islast, item in g("abc"): ... print(item, "(done)" if islast else "(to be continued)", sep="") ... a(to be continued) b(to be continued) c(done) but only used it once ore twice. > For context, I'm working my way through a (csv) file which describes > some database tables. I'm building the Oracle DDL to create that table > as I go. When I find myself building the last column, I want to finish > the definition with a ");" rather than the usual "," which occurs at the > end of all other column definitions... > > e.g. > CREATE TABLE wibble > ( > Col1 CHAR(2), > Col2 NUMBER(5,2), > ); This particular problem can idiomatically be addressed with str.join(): >>> print(",\n".join(["foo", "bar", "baz"])) foo, bar, baz From __peter__ at web.de Wed Oct 28 12:37:09 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 28 Oct 2015 17:37:09 +0100 Subject: [Tutor] Messy - Very Messy string manipulation. References: Message-ID: Vusa Moyo wrote: > I've written a script to remove vowels from a string/sentence. > > the while loop I'm using below is to take care of duplicate vowels found > in a sentence, ie > > anti_vowel('The cow moos louder than the frog') > > It works, but obviously its messy and n00by. Any suggestions on how I can > write this code better? (I'm assuming Python3) >>> 'The cow moos louder than the frog'.translate(str.maketrans("", "", "aeiouAEIOU")) 'Th cw ms ldr thn th frg' From __peter__ at web.de Wed Oct 28 12:54:52 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 28 Oct 2015 17:54:52 +0100 Subject: [Tutor] Demystification of Lambda Functions References: <007901d1111c$a31d54e0$e957fea0$@gmail.com> <20151028113648.GA10946@ando.pearwood.info> Message-ID: Steven D'Aprano wrote: > Sometimes callbacks are particularly short and simple. Suppose you are > programming a calculator, and you have ten buttons 0...9 which all do > precisely the same thing: they add their own name to the calculator > display: > > > for num in range(0, 10): > btn = Button(str(num), style="rectangle", > callback = lambda thebtn: display.add(thebtn.name) > ) > > > Much better than having to pre-define ten functions and add them to each > of the buttons. In this case the lambda obscures the fact that those ten functions are identical, so I'd prefer def add_digit(button): display.add(button.name) for num in range(10): button = Button(str(num), style="rectangle", callback=add_digit) From akleider at sonic.net Wed Oct 28 12:54:46 2015 From: akleider at sonic.net (Alex Kleider) Date: Wed, 28 Oct 2015 09:54:46 -0700 Subject: [Tutor] Messy - Very Messy string manipulation. In-Reply-To: References: Message-ID: <8544474c445fff72d30c8ffa8cdab869@sonic.net> On 2015-10-28 08:09, Vusa Moyo wrote: > Hi Guys, > > I've written a script to remove vowels from a string/sentence. > > the while loop I'm using below is to take care of duplicate vowels > found in > a sentence, ie > > anti_vowel('The cow moos louder than the frog') > > It works, but obviously its messy and n00by. Any suggestions on how I > can > write this code better? > > > ---- > def anti_vowel(text): > vowel = ['a', 'e', 'i', 'o', 'u'] > VOWEL = ['A', 'E', 'I', 'O', 'U'] > manip = [] > > for i in text: > manip.append(i) > fufu = 0 > # > while fufu < 16: > for x in vowel: > if x in manip: > manip.remove(x) > > for y in VOWEL: > if y in manip: > manip.remove(y) > > fufu = fufu + 2 > > strong = ''.join(manip) > return strong > > ---- > > Thanks - Vusa This struck me as a good place to utilize list comprehension. VOWELS = 'aeiouAEIOU' def remove_chars(s, chars2remove=VOWELS): """Returns the string s but without any of the characters found in chars2remove. If given only one parameter, defaults to removing vowels. """ s_as_list = [char for char in s] without_chars2remove = [ char for char in s_as_list if char not in chars2remove] # print(s_as_list) # for testing # print(without_chars2remove) # ditto return "".join(without_chars2remove) if __name__ == "__main__": print(remove_chars( 'The cow moos louder than the frog')) There may be some other constructs (the string join method on the empty string) to which you haven't yet been exposed. Confession: I'm submitting it probably as much to garner comments from the pundits as to help you. cheers, Alex From akleider at sonic.net Wed Oct 28 13:07:50 2015 From: akleider at sonic.net (Alex Kleider) Date: Wed, 28 Oct 2015 10:07:50 -0700 Subject: [Tutor] Messy - Very Messy string manipulation. In-Reply-To: References: Message-ID: <300a0b1628cf2840009ce6c2c494cb39@sonic.net> On 2015-10-28 09:37, Peter Otten wrote: > Vusa Moyo wrote: > >> I've written a script to remove vowels from a string/sentence. >> >> the while loop I'm using below is to take care of duplicate vowels >> found >> in a sentence, ie >> >> anti_vowel('The cow moos louder than the frog') >> >> It works, but obviously its messy and n00by. Any suggestions on how I >> can >> write this code better? > > (I'm assuming Python3) > >>>> 'The cow moos louder than the frog'.translate(str.maketrans("", "", > "aeiouAEIOU")) > 'Th cw ms ldr thn th frg' > I didn't know about the possibility of a third argument. Thanks, Peter. from the docs: """ static str.maketrans(x[, y[, z]]) This static method returns a translation table usable for str.translate(). If there is only one argument, it must be a dictionary mapping Unicode ordinals (integers) or characters (strings of length 1) to Unicode ordinals, strings (of arbitrary lengths) or None. Character keys will then be converted to ordinals. If there are two arguments, they must be strings of equal length, and in the resulting dictionary, each character in x will be mapped to the character at the same position in y. If there is a third argument, it must be a string, whose characters will be mapped to None in the result. """ Although not explicitly stated, I assume that if there is a third argument, the first 2 will be ignored. From alan.gauld at btinternet.com Wed Oct 28 13:25:36 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 28 Oct 2015 17:25:36 +0000 Subject: [Tutor] Messy - Very Messy string manipulation. In-Reply-To: References: Message-ID: On 28/10/15 16:37, Peter Otten wrote: >>>> 'The cow moos louder than the frog'.translate(str.maketrans("", "", > "aeiouAEIOU")) > 'Th cw ms ldr thn th frg' Even easier, forget the maketrans stuff and just use 'The cow moos louder than the frog'.translate(None,'aeiouAEIOU') -- 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 Oct 28 13:28:06 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 28 Oct 2015 18:28:06 +0100 Subject: [Tutor] Messy - Very Messy string manipulation. References: <300a0b1628cf2840009ce6c2c494cb39@sonic.net> Message-ID: Alex Kleider wrote: > On 2015-10-28 09:37, Peter Otten wrote: >> Vusa Moyo wrote: >> >>> I've written a script to remove vowels from a string/sentence. >>> >>> the while loop I'm using below is to take care of duplicate vowels >>> found >>> in a sentence, ie >>> >>> anti_vowel('The cow moos louder than the frog') >>> >>> It works, but obviously its messy and n00by. Any suggestions on how I >>> can >>> write this code better? >> >> (I'm assuming Python3) >> >>>>> 'The cow moos louder than the frog'.translate(str.maketrans("", "", >> "aeiouAEIOU")) >> 'Th cw ms ldr thn th frg' >> > > I didn't know about the possibility of a third argument. Thanks, Peter. > > from the docs: > """ > static str.maketrans(x[, y[, z]]) > > This static method returns a translation table usable for > str.translate(). > > If there is only one argument, it must be a dictionary mapping > Unicode ordinals (integers) or characters (strings of length 1) to > Unicode ordinals, strings (of arbitrary lengths) or None. Character keys > will then be converted to ordinals. > > If there are two arguments, they must be strings of equal length, > and in the resulting dictionary, each character in x will be mapped to > the character at the same position in y. If there is a third argument, > it must be a string, whose characters will be mapped to None in the > result. > """ > > Although not explicitly stated, I assume that if there is a third > argument, the first 2 will be ignored. Don't guess, fire up the interactive interpreter ;) >>> "abcdef".translate(str.maketrans("acf", "ACF", "bde")) 'ACF' All argument have an effect. Now have a look at the dict created by maketrans: >>> str.maketrans("acf", "ACF", "bde") {97: 65, 98: None, 99: 67, 100: None, 101: None, 102: 70} If the value is an int, str.translate() replaces chr(key) with chr(value), if the value is None chr(key) is removed. You can also replace one char with multiple chars, but for that you have to build the dict yourself: >>> "?hnlich ?blich l?blich".translate( ... {ord(a): b for a, b in [ ... ("?", "ae"), ("?", "oe"), ("?", "ue")]}) 'aehnlich ueblich loeblich' From breamoreboy at yahoo.co.uk Wed Oct 28 13:31:35 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Wed, 28 Oct 2015 17:31:35 +0000 Subject: [Tutor] Are there any Python-based GUI builders for tkinter In-Reply-To: <201510280839.t9S8dto9026889@fido.openend.se> References: <201510280839.t9S8dto9026889@fido.openend.se> Message-ID: On 28/10/2015 08:39, Laura Creighton wrote: > In a message of Tue, 27 Oct 2015 15:20:56 -0500, boB Stepp writes: >> I have a friend at work and he is trying to develop GUI applications >> in Python, but he does not want to hand-code them. Are there any >> commercial or non-commercial products that would do this for him? He >> tried his own online search but was unsuccessful. >> >> His OS is Mac OS 10.10 and is using Python 3.5. >> >> TIA! >> >> -- >> boB > > check out QtDesigner > > http://doc.qt.io/qt-5/qtdesigner-manual.html > > or QtCreator > http://www.qt.io/ide/ > > if you want the whole process to happen inside an IDE. > > https://wiki.python.org/moin/PyQt/Creating_GUI_Applications_with_PyQt_and_Qt_Designer may be useful as well, though its a little old by now. > > Laura > I was't aware that Qt would work with tkinter as given in the subject. Could you elaborate please? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From __peter__ at web.de Wed Oct 28 13:35:20 2015 From: __peter__ at web.de (Peter Otten) Date: Wed, 28 Oct 2015 18:35:20 +0100 Subject: [Tutor] Messy - Very Messy string manipulation. References: Message-ID: Alan Gauld wrote: > On 28/10/15 16:37, Peter Otten wrote: > >>>>> 'The cow moos louder than the frog'.translate(str.maketrans("", "", >> "aeiouAEIOU")) >> 'Th cw ms ldr thn th frg' > > Even easier, forget the maketrans stuff and just use > > 'The cow moos louder than the frog'.translate(None,'aeiouAEIOU') This only works for byte strings, not unicode. From lucasmascia at gmail.com Wed Oct 28 11:26:56 2015 From: lucasmascia at gmail.com (Lucas Mascia) Date: Wed, 28 Oct 2015 13:26:56 -0200 Subject: [Tutor] export pandas excel Message-ID: Hello, Attached is my program, I have filtered some data from an extensive table from excel. I have it running for two names: ps_sol = ["Mauro Cavalheiro Junior", "Aline Oliveira"] > for name in ps_sol: > .... At the end I am trying to export to another .xlsx file. But it is only saving the info of the last name in the list. I want it to save for all names that i list in my ps_sol Help please (: | VIEW MY | "It is not the strongest of the species that survives, nor the most intelligent that survives. It is the one that is most adaptable to change." - Darwin. -------------- next part -------------- import pandas as pd import sys #file loc R1 = input('Data do Relat?rio desejado (dd.mm) ---> ') loc = r'C:\Users\lucas.mascia\Downloads\relatorio-{0}.xlsx'.format(R1) ###################################################################### #Solicitantes ps_sol = ["Mauro Cavalheiro Junior", "Aline Oliveira"] #Aplicando filtros for name in ps_sol: #opening file df = pd.read_excel(loc) dfps = df[[2,15,16,17]] #apply filter f1 = dfps[(dfps['Cliente']=="POSTAL SAUDE") & (dfps['Nome do solicitante']==name)] #print info print (''' ============================================================= Relatorio do dia: {} Cliente: POSTAL SAUDE Solicitante: {} ============================================================= '''.format(R1, name)) print (f1) f1.to_excel('C:/Users/lucas.mascia/Downloads/ps_sol.xlsx', sheet_name=name) From alan.gauld at btinternet.com Wed Oct 28 14:06:10 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 28 Oct 2015 18:06:10 +0000 Subject: [Tutor] Messy - Very Messy string manipulation. In-Reply-To: References: Message-ID: On 28/10/15 17:35, Peter Otten wrote: > Alan Gauld wrote: > >> On 28/10/15 16:37, Peter Otten wrote: >> >>>>>> 'The cow moos louder than the frog'.translate(str.maketrans("", "", >>> "aeiouAEIOU")) >>> 'Th cw ms ldr thn th frg' >> >> Even easier, forget the maketrans stuff and just use >> >> 'The cow moos louder than the frog'.translate(None,'aeiouAEIOU') > > This only works for byte strings, not unicode. Aha, I tried it in Python 2.7 which worked, but I didn't think about v3... -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From zachary.ware+pytut at gmail.com Wed Oct 28 15:06:00 2015 From: zachary.ware+pytut at gmail.com (Zachary Ware) Date: Wed, 28 Oct 2015 14:06:00 -0500 Subject: [Tutor] Messy - Very Messy string manipulation. In-Reply-To: References: Message-ID: On Wed, Oct 28, 2015 at 11:09 AM, Zachary Ware wrote: > return ''.join(c for c in text if c not in vowels Looking again, I see I typo'd here too. There should of course be a ')' at the end. -- Zach From cs at zip.com.au Wed Oct 28 18:22:50 2015 From: cs at zip.com.au (Cameron Simpson) Date: Thu, 29 Oct 2015 09:22:50 +1100 Subject: [Tutor] How do I (idiomatically) determine when I'm looking at the last entry in a list? In-Reply-To: <5C71288A643C6249B50BC6B27CB3A14C020412F7@CAPPRWMMBX23.central.ad.capita.co.uk> References: <5C71288A643C6249B50BC6B27CB3A14C020412F7@CAPPRWMMBX23.central.ad.capita.co.uk> Message-ID: <20151028222250.GA62408@cskk.homeip.net> On 28Oct2015 14:48, Flynn, Stephen (L & P - IT) wrote: > Python 3. > > I'm iterating through a list and I'd like to know when I'm at >the end of the said list, so I can do something different. For example > >list_of_things = ['some', 'special', 'things'] >for each_entry in list_of_things: > print(each_entry) > if each_entry == list_of_things[-1]: # do something special to >last entry > ...etc > >Is this the idiomatic way to detect you're at the last entry in a list >as you iterate through it? If it really is a list then enumerate is your friend. list_of_things = ['some', 'special', 'things'] last_index = len(list_of_things) - 1 for index, each_entry in enumerate(list_of_things): print(each_entry) if index == last_index: ... special stuff for the last index ... >For context, I'm working my way through a (csv) file which describes >some database tables. I'm building the Oracle DDL to create that table >as I go. When I find myself building the last column, I want to finish >the definition with a ");" rather than the usual "," which occurs at the >end of all other column definitions... This is a bit different, in that you are probably not using a list: you don't know how long the sequence is. I build things like that this way: fp.write('CREATE TABLE wibble\n(') sep = '\n ' for item in items: fp.write(sep) fp.write(... column definition for item ...) sep = ',\n ' fp.write('\n);\n') i.e. instead of printing the separator _after_ each item, print it _before_. That way you can special case the first occasion and use a comma for each successive occasion. Cheers, Cameron Simpson Why is it whatever we don't understand is called a 'thing'? - "Bones" McCoy From lac at openend.se Wed Oct 28 18:32:57 2015 From: lac at openend.se (Laura Creighton) Date: Wed, 28 Oct 2015 23:32:57 +0100 Subject: [Tutor] Are there any Python-based GUI builders for tkinter In-Reply-To: References: <201510280839.t9S8dto9026889@fido.openend.se> Message-ID: <201510282232.t9SMWvFf024582@fido.openend.se> In a message of Wed, 28 Oct 2015 17:31:35 +0000, Mark Lawrence writes: >On 28/10/2015 08:39, Laura Creighton wrote: >> In a message of Tue, 27 Oct 2015 15:20:56 -0500, boB Stepp writes: >>> I have a friend at work and he is trying to develop GUI applications >>> in Python, but he does not want to hand-code them. Are there any >>> commercial or non-commercial products that would do this for him? He >>> tried his own online search but was unsuccessful. >>> >>> His OS is Mac OS 10.10 and is using Python 3.5. >>> >>> TIA! >>> >>> -- >>> boB >> >> check out QtDesigner >> >> http://doc.qt.io/qt-5/qtdesigner-manual.html >> >> or QtCreator >> http://www.qt.io/ide/ >> >> if you want the whole process to happen inside an IDE. >> >> https://wiki.python.org/moin/PyQt/Creating_GUI_Applications_with_PyQt_and_Qt_Designer may be useful as well, though its a little old by now. >> >> Laura >> > >I was't aware that Qt would work with tkinter as given in the subject. >Could you elaborate please? I actually only read the text of the letter, and not the subject line. So I assumed any gui toolkit he did not have to build himself that would work with python would be fine. Laura From alan.gauld at btinternet.com Wed Oct 28 19:25:44 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Wed, 28 Oct 2015 23:25:44 +0000 Subject: [Tutor] export pandas excel In-Reply-To: References: Message-ID: On 28/10/15 15:26, Lucas Mascia wrote: > Hello, > > Attached is my program, When its a short program(<100 lines say) just include it in the text. Attachments often get rejected by email gateways, especially on corporate firewalls or for mobile devices. ================================= import pandas as pd import sys #file loc R1 = input('Data do Relat?rio desejado (dd.mm) ---> ') loc = r'C:\Users\lucas.mascia\Downloads\relatorio-{0}.xlsx'.format(R1) ###################################################################### #Solicitantes ps_sol = ["Mauro Cavalheiro Junior", "Aline Oliveira"] #Aplicando filtros for name in ps_sol: #opening file df = pd.read_excel(loc) dfps = df[[2,15,16,17]] #apply filter f1 = dfps[(dfps['Cliente']=="POSTAL SAUDE") & (dfps['Nome do solicitante']==name)] #print info print (''' ============================================================= Relatorio do dia: {} Cliente: POSTAL SAUDE Solicitante: {} ============================================================= '''.format(R1, name)) print (f1) f1.to_excel('C:/Users/lucas.mascia/Downloads/ps_sol.xlsx', sheet_name=name) =============================== > At the end I am trying to export to another .xlsx file. But it is only > saving the info of the last name in the list. Pandas is outside the scope of this list so I don't know much about it. But is it possible that to_excel() creates a new file each time? Is there an append flag you can pass maybe? Finally in the line starting f1=dfps... Is that really supposed to be a bitwise AND (&) operation? It seems unlikely given the two operands are both boolean values. It should work but it looks wrong. I would expect a logical AND (and). I can't comment on the rest because it is too pandas (and data ) specific to make any sense to 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 steve at pearwood.info Wed Oct 28 19:41:56 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 29 Oct 2015 10:41:56 +1100 Subject: [Tutor] How do I (idiomatically) determine when I'm looking at the last entry in a list? In-Reply-To: <5C71288A643C6249B50BC6B27CB3A14C020412F7@CAPPRWMMBX23.central.ad.capita.co.uk> References: <5C71288A643C6249B50BC6B27CB3A14C020412F7@CAPPRWMMBX23.central.ad.capita.co.uk> Message-ID: <20151028234156.GB10946@ando.pearwood.info> On Wed, Oct 28, 2015 at 02:48:05PM +0000, Flynn, Stephen (L & P - IT) wrote: > I'm iterating through a list and I'd like to know when I'm at > the end of the said list, so I can do something different. For example > > list_of_things = ['some', 'special', 'things'] > for each_entry in list_of_things: > print(each_entry) > if each_entry == list_of_things[-1]: # do something special to > last entry > ...etc > > > Is this the idiomatic way to detect you're at the last entry in a list > as you iterate through it? But it doesn't detect the last entry. Consider: list_of_things = ["cheese", "fruit", "cheese", "fish", "cheese"] Your code will perform the special processing three times. There's no idiomatic way to do this because it is a fairly unusual thing to do. Normally we want to process all the items in a list the same way. But here are some solutions: (1) Avoid the problem altogether by arranging matters so that the "last item" isn't in the list at all. list_of_things = ['some', 'special'] last = 'things' for each_entry in list_of_things: print(each_entry) print(last.upper()) (2) Slicing. Requires a little extra memory, but is probably the closest to an idiomatic solution for this sort of thing. list_of_things = ['some', 'special', 'things'] for each_entry in list_of_things[:-1]: print(each_entry) print(list_of_things[-1].upper()) (3) Add a sentinel to the list. list_of_things = ['some', 'special', None, 'things'] for each_entry in list_of_things: if each_entry is None: break print(each_entry) print(list_of_things[-1].upper()) (4) Count the items. list_of_things = ['some', 'special', 'things'] for i, each_entry in enumerate(list_of_things): if i == len(list_of_things) - 1: # Watch out for off-by-one errors! each_entry = each_entry.upper() print(each_entry) (5) What if you're dealing with an iterable of unknown length that can't be sliced? The obvious answer is to convert to a list: list_of_things = list(things) but suppose you have some reason for not wanting to do that. (Perhaps things is truly huge, billions of items.) Something like this should help: prev = [] for this in things: if prev: print(prev[0]) prev = [this] print(prev[0].upper()) We can make this a little more efficient if things is an actual iterator: things = iter(things) try: prev = next(things) except StopIteration: # No things at all. pass else: for this in things: print(prev) prev = this print(prev.upper()) -- Steve From steve at pearwood.info Wed Oct 28 19:55:03 2015 From: steve at pearwood.info (Steven D'Aprano) Date: Thu, 29 Oct 2015 10:55:03 +1100 Subject: [Tutor] How do I (idiomatically) determine when I'm looking at the last entry in a list? In-Reply-To: <5C71288A643C6249B50BC6B27CB3A14C020412F7@CAPPRWMMBX23.central.ad.capita.co.uk> References: <5C71288A643C6249B50BC6B27CB3A14C020412F7@CAPPRWMMBX23.central.ad.capita.co.uk> Message-ID: <20151028235503.GC10946@ando.pearwood.info> Wait, I have another comment... On Wed, Oct 28, 2015 at 02:48:05PM +0000, Flynn, Stephen (L & P - IT) wrote: > I'm iterating through a list and I'd like to know when I'm at > the end of the said list, so I can do something different. For example [...] > For context, I'm working my way through a (csv) file which describes > some database tables. I'm building the Oracle DDL to create that table > as I go. When I find myself building the last column, I want to finish > the definition with a ");" rather than the usual "," which occurs at the > end of all other column definitions... Then you don't need to know when you're at the end of the list. See below. But firstly, and MOST IMPORTANTLY, how are you sanitizing your input? http://bobby-tables.com/ Code injection attacks are now #1 risk factor for code, above buffer overflows. So, assuming you have sanitized your input, or trust it more than you trust your own code (you run tests on your own code, right?), let's see how to build up a string like: "FUNCTION(a,b,c,d,e);" with some variable number of string arguments a, b, c, ... args = ["5", "2", "7", "1", "0", "3"] result = "FUNCTION(%s);" % ','.join(args) This will do the right thing whether there is one argument or twenty, or even no arguments at all. The "join" method inserts the first string *between* each of the list items. It deals correctly with the "no items" and "one item" cases: py> "--".join([]) '' py> "--".join(["spam"]) 'spam' py> "--".join(["spam", "eggs"]) 'spam--eggs' py> "--".join(["spam", "eggs", "cheese"]) 'spam--eggs--cheese' so you don't have to worry about counting items or determining the last item, you just join them. -- Steve From breamoreboy at yahoo.co.uk Wed Oct 28 20:22:48 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 29 Oct 2015 00:22:48 +0000 Subject: [Tutor] Are there any Python-based GUI builders for tkinter In-Reply-To: <201510282232.t9SMWvFf024582@fido.openend.se> References: <201510280839.t9S8dto9026889@fido.openend.se> <201510282232.t9SMWvFf024582@fido.openend.se> Message-ID: On 28/10/2015 22:32, Laura Creighton wrote: > In a message of Wed, 28 Oct 2015 17:31:35 +0000, Mark Lawrence writes: >> On 28/10/2015 08:39, Laura Creighton wrote: >>> In a message of Tue, 27 Oct 2015 15:20:56 -0500, boB Stepp writes: >>>> I have a friend at work and he is trying to develop GUI applications >>>> in Python, but he does not want to hand-code them. Are there any >>>> commercial or non-commercial products that would do this for him? He >>>> tried his own online search but was unsuccessful. >>>> >>>> His OS is Mac OS 10.10 and is using Python 3.5. >>>> >>>> TIA! >>>> >>>> -- >>>> boB >>> >>> check out QtDesigner >>> >>> http://doc.qt.io/qt-5/qtdesigner-manual.html >>> >>> or QtCreator >>> http://www.qt.io/ide/ >>> >>> if you want the whole process to happen inside an IDE. >>> >>> https://wiki.python.org/moin/PyQt/Creating_GUI_Applications_with_PyQt_and_Qt_Designer may be useful as well, though its a little old by now. >>> >>> Laura >>> >> >> I was't aware that Qt would work with tkinter as given in the subject. >> Could you elaborate please? > > I actually only read the text of the letter, and not the subject > line. So I assumed any gui toolkit he did not have to build himself > that would work with python would be fine. > > Laura > How many times do I have to say this, never assume anything, and I assume that you're okay with that? :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From soweto at gmail.com Thu Oct 29 03:12:55 2015 From: soweto at gmail.com (Vusa Moyo) Date: Thu, 29 Oct 2015 09:12:55 +0200 Subject: [Tutor] Messy - Very Messy string manipulation. In-Reply-To: References: Message-ID: Thanks Meenu. str.translate. Worked like a charm for python 3.5. And thanks Alan Gauld for the 2.7 version. Appreciate the help guys. You guys are awesome. Regards Vusa On Wed, Oct 28, 2015 at 6:23 PM, meenu ravi wrote: > Hi Vusa, > > I was not able to reply through mail list due to some issue. So just > replying through email. > > We can make use of string translate method for more pythonic way. If you > are using python 2.x, the following itself should work for you: > > *************************************************************************** > import string > def anti_vowel(str): > word = str.translate(None, 'aeiouAEIOU') > return word > > print anti_vowel('The cow moos louder than the frog') > *************************************************************************** > > And if you are using python 3.x, "None" inside the str.translate method > doesn't work. So instead, you can use in this way: > > *************************************************************************** > import string > def anti_vowel(str): > word = str.translate(str.maketrans("","","aeiouAEIOU")) > return(word) > > print(anti_vowel("The cow moos louder than the frog")) > > > *************************************************************************** > > The above code should work with python 2.x as well with python 2 syntax as > follows: > > import string > def anti_vowel(str): > word = str.translate(string.maketrans('', ''), 'aeiouAEIOU') > return word > > print anti_vowel('The cow moos louder than the frog') > > > If you want to know more about translate method, please follow the link, > https://docs.python.org/2/library/string.html#string-functions > > I hope you will get much more options through mailing list. > > Happy python:) > > Thanks, > Meenakshi > From breamoreboy at yahoo.co.uk Thu Oct 29 03:50:32 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Thu, 29 Oct 2015 07:50:32 +0000 Subject: [Tutor] Messy - Very Messy string manipulation. In-Reply-To: References: Message-ID: On 28/10/2015 18:06, Alan Gauld wrote: > On 28/10/15 17:35, Peter Otten wrote: >> Alan Gauld wrote: >> >>> On 28/10/15 16:37, Peter Otten wrote: >>> >>>>>>> 'The cow moos louder than the frog'.translate(str.maketrans("", "", >>>> "aeiouAEIOU")) >>>> 'Th cw ms ldr thn th frg' >>> >>> Even easier, forget the maketrans stuff and just use >>> >>> 'The cow moos louder than the frog'.translate(None,'aeiouAEIOU') >> >> This only works for byte strings, not unicode. > > Aha, I tried it in Python 2.7 which worked, but I didn't > think about v3... > Seems like as good a place as any to point out that in Python 3 all of the following also exist. static bytes.maketrans(from, to) bytes.translate(table[, delete]) static bytearray.maketrans(from, to) bytearray.translate(table[, delete]) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From pscott_74 at yahoo.com Thu Oct 29 15:11:31 2015 From: pscott_74 at yahoo.com (Patti Scott) Date: Thu, 29 Oct 2015 12:11:31 -0700 Subject: [Tutor] counter not working in Quick Sort script Message-ID: <1446145891.57460.YahooMailBasic@web141604.mail.bf1.yahoo.com> Mac OS 10.10 Python 3.4.3 I self-study Python and am using it for a Coursera algorithm class. Hi! My script sorts correctly on all my test arrays. My accumulator variable to count the number of comparisons returns nonsense. I'm counting the (length - one) of each sublist that will be sorted in place, not the individual comparisons. I put in a print statement for the count variable, and the expected values print, but the function seems to be returning the first increment of the count variable instead of the final value. I reread on the difference between print and return, but I haven't figured this out yet. I think I'm doing something language-specific wrong would appreciate another set of eyes. def partition(A, start, stop): p = A[start] # make pivot first element in partition i = start + 1 for j in range(i, stop): # swap elements if A[j] bigger than pivot if A[j] < p: A[j], A[i] = A[i], A[j] i += 1 # swap pivot into sorted index A[start], A[i-1] = A[i-1], A[start] return i def quick_sort(A, start, stop, count): if start < stop: # increment count by length of partition less the pivot count += (stop - start - 1) print(count) split = partition(A, start, stop) # recursively sort lower partition quick_sort(A, start, split-1, count) # recursively count upper partition quick_sort(A, split, stop, count) return count def main(): unsorted = [ 1, 2, 3, 4, 5, 6, 7, 8 ] count = quick_sort(unsorted, 0, len(unsorted), 0) print(unsorted) print("There are {} comparisons.".format(count)) main() This code is giving me this output: ? algorithms python3 quick_sort_first.py 7 13 18 22 25 27 28 28 [1, 2, 3, 4, 5, 6, 7, 8] There are 7 comparisons. Thank you, Patricia From alan.gauld at btinternet.com Thu Oct 29 21:12:50 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 30 Oct 2015 01:12:50 +0000 Subject: [Tutor] counter not working in Quick Sort script In-Reply-To: <1446145891.57460.YahooMailBasic@web141604.mail.bf1.yahoo.com> References: <1446145891.57460.YahooMailBasic@web141604.mail.bf1.yahoo.com> Message-ID: On 29/10/15 19:11, Patti Scott via Tutor wrote: Caveat: I didn't check the algorithms for correctness, I'll just take your word for that. > My accumulator variable to count the number of comparisons returns nonsense. > def quick_sort(A, start, stop, count): > if start < stop: > # increment count by length of partition less the pivot > count += (stop - start - 1) > print(count) > split = partition(A, start, stop) > > # recursively sort lower partition > quick_sort(A, start, split-1, count) > # recursively count upper partition > quick_sort(A, split, stop, count) > > return count Notice that you only set count once at the top of the function. What the recursive instances of the function do is irrelevant because you don't use their return values. So the return value of this function is always (count + stop - start -1) for the initial invocation value of count. I suspect you really want to do something to count based on the returns from the recursive calls too. > def main(): > unsorted = [ 1, 2, 3, 4, 5, 6, 7, 8 ] This looks very sorted to me? Is that correct? > count = quick_sort(unsorted, 0, len(unsorted), 0) count should return 0+len()-0-1 -> len-1 = 7 > print(unsorted) > print("There are {} comparisons.".format(count)) > > main() > > > This code is giving me this output: > > ? algorithms python3 quick_sort_first.py > 7 This is the outer functions count > 13 > 18 > 22 > 25 > 27 > 28 > 28 These are the recursive values of count which are invisible to the outer invocation > [1, 2, 3, 4, 5, 6, 7, 8] This is the sorted result > There are 7 comparisons. And this reflects the outer value of count again. Your code does exactly what you told it to do. Your problem is that you are not using the returned counts from the recursive calls. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From sneely91 at icloud.com Thu Oct 29 21:27:43 2015 From: sneely91 at icloud.com (Shelby Neely) Date: Thu, 29 Oct 2015 20:27:43 -0500 Subject: [Tutor] For Loop Message-ID: <6C1E3E9D-47CD-4073-9BF3-F9E997379400@icloud.com> Hi, I was wondering if someone can complete a for loop in an array for me. Thank you From alan.gauld at btinternet.com Fri Oct 30 07:32:56 2015 From: alan.gauld at btinternet.com (Alan Gauld) Date: Fri, 30 Oct 2015 11:32:56 +0000 Subject: [Tutor] For Loop In-Reply-To: <6C1E3E9D-47CD-4073-9BF3-F9E997379400@icloud.com> References: <6C1E3E9D-47CD-4073-9BF3-F9E997379400@icloud.com> Message-ID: On 30/10/15 01:27, Shelby Neely wrote: > Hi, I was wondering if someone can complete a for loop in an array for me. for item in anArray: print(item) If that doesn't help then you are going to have to explain more about what exactly you want to know. Show us your code, explain what you expected to happen and what isn't working. Show us any error messages. Tell us your Python version and OS too. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From pscott_74 at yahoo.com Fri Oct 30 12:53:32 2015 From: pscott_74 at yahoo.com (Patti Scott) Date: Fri, 30 Oct 2015 09:53:32 -0700 Subject: [Tutor] counter not working in Quick Sort script In-Reply-To: Message-ID: <1446224012.83141.YahooMailBasic@web141603.mail.bf1.yahoo.com> That make sense, thank you. I changed the quick_sort() to def quick_sort(A, start, stop, count): if start < stop: # increment count by length of partition less the pivot count += (stop - start - 1) print(count) split = partition(A, start, stop) # recursively sort lower partition left = quick_sort(A, start, split-1, count) if left: count = left # recursively count upper partition right = quick_sort(A, split, stop, count) if right: count = right return count Yes, the sorting worked on all the *lists I tested.* For counting comparisons, I used a sorted list with a known number of comparisons to be able check the accumulator variable. -Patricia -------------------------------------------- On Thu, 10/29/15, Alan Gauld wrote: Subject: Re: [Tutor] counter not working in Quick Sort script To: tutor at python.org Date: Thursday, October 29, 2015, 9:12 PM On 29/10/15 19:11, Patti Scott via Tutor wrote: Caveat: I didn't check the algorithms for correctness, I'll just take your word for that. > My accumulator variable to count the number of comparisons returns nonsense. > def quick_sort(A, start, stop, count): >? ? ? if start < stop: >? ? ? ? ? # increment count by length of partition less the pivot >? ? ? ? ? count += (stop - start - 1) >? ? ? ? ? print(count) >? ? ? ? ? split = partition(A, start, stop) > >? ? ? ? ? # recursively sort lower partition >? ? ? ? ? quick_sort(A, start, split-1, count) >? ? ? ? ? # recursively count upper partition >? ? ? ? ? quick_sort(A, split, stop, count) > >? ? ? ? ? return count Notice that you only set count once at the top of the function. What the recursive instances of the function do is irrelevant because you don't use their return values. So the return value of this function is always (count + stop - start -1) for the initial invocation value of count. I suspect you really want to do something to count based on the returns from the recursive calls too. > def main(): >? ? ? unsorted = [ 1, 2, 3, 4, 5, 6, 7, 8 ] This looks very sorted to me? Is that correct? >? ? ? count = quick_sort(unsorted, 0, len(unsorted), 0) count should return 0+len()-0-1 -> len-1 = 7 >? ? ? print(unsorted) >? ? ? print("There are {} comparisons.".format(count)) > > main() > > > This code is giving me this output: > > ?? algorithms? python3 quick_sort_first.py > 7 This is the outer functions count > 13 > 18 > 22 > 25 > 27 > 28 > 28 These are the recursive values of count which are invisible to the outer invocation > [1, 2, 3, 4, 5, 6, 7, 8] This is the sorted result > There are 7 comparisons. And this reflects the outer value of count again. Your code does exactly what you told it to do. Your problem is that you are not using the returned counts from the recursive calls. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist? -? Tutor at python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor From martin at linux-ip.net Fri Oct 30 13:48:17 2015 From: martin at linux-ip.net (Martin A. Brown) Date: Fri, 30 Oct 2015 10:48:17 -0700 Subject: [Tutor] For Loop In-Reply-To: <6C1E3E9D-47CD-4073-9BF3-F9E997379400@icloud.com> References: <6C1E3E9D-47CD-4073-9BF3-F9E997379400@icloud.com> Message-ID: Hello Shelby, > I was wondering if someone can complete a for loop in an array for > me. Your question is a bit too terse. You don't give us too much detail in understanding what you want to do. But, we are the Tutor list and we are here to help! Here are a few things which may help you get started.... * A few other programming languages refer to an array as a basic data type. In Python, it is the 'list', which is the analogous basic data type (although there is a an 'array' data type). You should start by learning how to use a Python 'list', though. * A for loop on a list is very easy. Here's a Python3 code snippet: data = list(range(10)) # -- put 10 elements in a list for item in data: print(item) * You may find it helpful to work through some tutorial material. There are many. We can help you choose one if you tell us what you are trying to do. I will suggest the main Python tutorial at the language documentation site as a starting place. Since you asked about for loops, you probably want to read about control flow. https://docs.python.org/3/tutorial/ https://docs.python.org/3/tutorial/controlflow.html If you have more specific details on what you are trying to accomplish and/or learn, then send along those questions! Good luck as you get started, -Martin -- Martin A. Brown http://linux-ip.net/ From badouglas at gmail.com Fri Oct 30 16:06:44 2015 From: badouglas at gmail.com (bruce) Date: Fri, 30 Oct 2015 16:06:44 -0400 Subject: [Tutor] ncurses question Message-ID: Hi. Looking over various sites on ncurses. Curious. I see various chunks of code for creating multiple windows.. But I haven't seen any kind of example that shows how to 'move' or switch between multiple windows. Anyone have any code sample, or any tutorial/site that you could point me to! I'm thinking of putting together a simple test to be able to select between a couple of test windows, select the given field in the window, and then generate the results in a lower window based on what's selected.. Just curious. Any pointers, greatly appreciated. Thanks From lac at openend.se Fri Oct 30 17:39:19 2015 From: lac at openend.se (Laura Creighton) Date: Fri, 30 Oct 2015 22:39:19 +0100 Subject: [Tutor] ncurses question In-Reply-To: References: Message-ID: <201510302139.t9ULdJkp004427@fido.openend.se> In a message of Fri, 30 Oct 2015 16:06:44 -0400, bruce writes: >Hi. > >Looking over various sites on ncurses. Curious. I see various chunks >of code for creating multiple windows.. But I haven't seen any kind of >example that shows how to 'move' or switch between multiple windows. > >Anyone have any code sample, or any tutorial/site that you could point me to! > >I'm thinking of putting together a simple test to be able to select >between a couple of test windows, select the given field in the >window, and then generate the results in a lower window based on >what's selected.. > >Just curious. Any pointers, greatly appreciated. > >Thanks I went looking and found this: http://www.tuxradar.com/content/code-project-build-ncurses-ui-python#null but I think you are going to have to believe Eric Raymond when he mentions here: http://invisible-island.net/ncurses/ncurses-intro.html newterm(type, ofp, ifp) A program which outputs to more than one terminal should use newterm() instead of initscr(). newterm() should be called once for each terminal. It returns a variable of type SCREEN * which should be saved as a reference to that terminal. (NOTE: a SCREEN variable is not a screen in the sense we are describing in this introduction, but a collection of parameters used to assist in optimizing the display.) The arguments are the type of the terminal (a string) and FILE pointers for the output and input of the terminal. If type is NULL then the environment variable $TERM is used. endwin() should called once at wrapup time for each terminal opened using this function. set_term(new) This function is used to switch to a different terminal previously opened by newterm(). The screen reference for the new terminal is passed as the parameter. The previous terminal is returned by the function. All other calls affect only the current terminal. That paper is talking about ncurses and C, but since as far as I know all that the python bindings do is wrap the same things, it should be true there, as well. But I have no working code, so take this with the appropriate amount of salt .... Laura From dyoo at hashcollision.org Fri Oct 30 19:58:03 2015 From: dyoo at hashcollision.org (Danny Yoo) Date: Fri, 30 Oct 2015 16:58:03 -0700 Subject: [Tutor] For Loop In-Reply-To: References: <6C1E3E9D-47CD-4073-9BF3-F9E997379400@icloud.com> Message-ID: On Fri, Oct 30, 2015 at 10:48 AM, Martin A. Brown wrote: > > Hello Shelby, > >> I was wondering if someone can complete a for loop in an array for >> me. > > Your question is a bit too terse. You don't give us too much detail > in understanding what you want to do. Also, we have no idea *why* you want to do what you're asking. "Why" is important. The reason is because, since you're presumably a beginner, you might not realize that you're asking is something possibly nonsensical. I'm being serious. As a programmer, it's all too easy for us to answer the wrong question because we haven't double-checked the "why" to make sure it makes internal sense. It's especially problematic for programmers because there's a temptation to rush toward a problem's solution before asking oneself: "Is this even a good idea?" [For rest of the Tutor group: an interesting example of this situation is in the "Cracking the Oyster" chapter of Programming Pearls (http://www.amazon.com/Programming-Pearls-2nd-Edition-Bentley/dp/0201657880). It describes a scenario where the solution hinged, not directly on the question being asked, but on why the question was asked.] Anyway, any details about what you already know, and what you think you might need help with, these are details that will make it easier for us to help. Let us know. Good luck! From carroll at tjc.com Fri Oct 30 20:00:52 2015 From: carroll at tjc.com (Terry Carroll) Date: Fri, 30 Oct 2015 17:00:52 -0700 (PDT) Subject: [Tutor] Plotting with python Message-ID: If you were going to get started doing some simple plotting with Python 2.7 (in my case, I'm simply plotting temperature against time-of-day) what would you use? - matplotlib [1] - gnuplot [2] - something else entirely? Assume no substantial familiarity with the underlying plotting software, let alone the Python bindings. The only thing I can think of that might be special is to specify the upper/lower bounds of the plot; for example, in my case, I know the temperatures vary between somewhere around 70-78 degrees F., so I'd want the Y-axis to go, say 60-90, not arbitrarily start at zero; but I suspect this is a pretty standard thing in almost any plotting package. [1] http://matplotlib.org/api/pyplot_api.html [2] http://gnuplot-py.sourceforge.net/ From breamoreboy at yahoo.co.uk Fri Oct 30 22:24:45 2015 From: breamoreboy at yahoo.co.uk (Mark Lawrence) Date: Sat, 31 Oct 2015 02:24:45 +0000 Subject: [Tutor] Plotting with python In-Reply-To: References: Message-ID: On 31/10/2015 00:00, Terry Carroll wrote: > If you were going to get started doing some simple plotting with Python > 2.7 (in my case, I'm simply plotting temperature against time-of-day) > what would you use? > > - matplotlib [1] > - gnuplot [2] > - something else entirely? > > Assume no substantial familiarity with the underlying plotting software, > let alone the Python bindings. > > The only thing I can think of that might be special is to specify the > upper/lower bounds of the plot; for example, in my case, I know the > temperatures vary between somewhere around 70-78 degrees F., so I'd want > the Y-axis to go, say 60-90, not arbitrarily start at zero; but I > suspect this is a pretty standard thing in almost any plotting package. > > [1] http://matplotlib.org/api/pyplot_api.html > [2] http://gnuplot-py.sourceforge.net/ > matplotlib, I gave up gnuplot in favour of it maybe 15 years ago and have never looked back. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence From martin at linux-ip.net Sat Oct 31 01:57:39 2015 From: martin at linux-ip.net (Martin A. Brown) Date: Fri, 30 Oct 2015 22:57:39 -0700 Subject: [Tutor] Plotting with python In-Reply-To: References: Message-ID: >> If you were going to get started doing some simple plotting with Python >> 2.7 (in my case, I'm simply plotting temperature against time-of-day) >> what would you use? >> >> - matplotlib [1] >> - gnuplot [2] >> - something else entirely? >> >> Assume no substantial familiarity with the underlying plotting software, >> let alone the Python bindings. >> >> The only thing I can think of that might be special is to specify the >> upper/lower bounds of the plot; for example, in my case, I know the >> temperatures vary between somewhere around 70-78 degrees F., so I'd want >> the Y-axis to go, say 60-90, not arbitrarily start at zero; but I >> suspect this is a pretty standard thing in almost any plotting package. >> >> [1] http://matplotlib.org/api/pyplot_api.html >> [2] http://gnuplot-py.sourceforge.net/ > > matplotlib, I gave up gnuplot in favour of it maybe 15 years ago and have never > looked back. I think my transition was later and I'm modestly bilingual with these tools. However, in principle, I agree with Mark--IF you are primarily using Python as your tool for massaging and exploring data. If you are, then I might add one more suggestion. There's a project called 'IPython' [0] which has built a very nicely extended and richer interactive interface to the Python interpreter. You can use IPython as a replacement for the Python interactive shell. I have for years, and it's wonderful (even though, I also use the interactive shell that ships with the system supplied Python I use). Why am I talking about IPython? Aside from other benefits, the IPython Notebook [1] is directly useful to those who are also matplotlib users, because it allows you to record an entire analysis session, display graphics inline (see macro "%matplotlib inline") and then later, share the data explorations in a web browser. N.B. I have not found any running, public IPython Notebooks. This doesn't surprise me, because of the security risks of allowing just anybody access to a Python instance is like letting strangers into your kitchen. They might eat all of your food, or try to crack that safe behind the portrait in the dining room. http://calebmadrigal.com/graph-ipython-notebook/ So, if I were in your shoes, starting today, I'd install IPython and matplotlib and then fire up the IPython Notebook on my local machine, type '%matplotlib inline' and start trying to display my data. One nice feature of matplotlib is that it autoscales by default. So, if all of your values (temperature) are within the range you want to display, you don't need to mess with the axes. See their tutorial: http://matplotlib.org/users/pyplot_tutorial.html Good luck and enjoy! -Martin [0] http://ipython.org/ [1] http://ipython.org/notebook.html -- Martin A. Brown http://linux-ip.net/ From lac at openend.se Sat Oct 31 02:33:23 2015 From: lac at openend.se (Laura Creighton) Date: Sat, 31 Oct 2015 07:33:23 +0100 Subject: [Tutor] Plotting with python In-Reply-To: References: Message-ID: <201510310633.t9V6XNdw011038@fido.openend.se> I'd use matplotlib, unless the ultimate goal is to render onto a webpage. Then I would use bokeh. http://bokeh.pydata.org/en/latest/ Laura From nymcity at yahoo.com Sat Oct 31 10:43:20 2015 From: nymcity at yahoo.com (Nym City) Date: Sat, 31 Oct 2015 14:43:20 +0000 (UTC) Subject: [Tutor] Custom Function that Takes argument In-Reply-To: References: Message-ID: <812333270.192412.1446302600207.JavaMail.yahoo@mail.yahoo.com> Hello, Thank you for your response. I went back and updated encoding to utf-8 and ASCII but I still experienced issues with the output. The part that is interesting is that the output for each of the following fields is the (should be) the same??? 1.Search by City ??? 2.Search by Region (State Abbreviation) ??? 3.Search by Zip Search by zip comes out just fine but only the partial output is shared for the first two options. I don't understand why that would be? I would think if its the same output for all three options that I would either work for all three or not work for any. Also, why the partial results. Any suggestions on how to normalize this? ?Thank you. On Wednesday, October 21, 2015 5:53 AM, Alan Gauld wrote: On 21/10/15 01:18, Nym City via Tutor wrote: > def zip_search(query): >? ? ? api_key = locu_api >? ? ? url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key >? ? ? zip = query.replace(' ', '%20') >? ? ? final_url = url + '&zip=' + zip + "&category=restaurant" >? ? ? jason_obj = urllib2.urlopen(final_url) >? ? ? data = json.load(jason_obj) >? ? ? for item in data['objects']: >? ? ? ? ? print item['name'], item['phone'], item['street_address'], item['categories'], item['website_url'] > > ans=True > while ans: >? ? ? print (""" >? ? ? 1.Search by City >? ? ? 2.Search by Region (State Abbreviation) >? ? ? 3.Search by Zip >? ? ? 4.Exit/Quit >? ? ? """) >? ? ? ans=raw_input("What would you like to do? ") >? ? ? if ans=="1": >? ? ? ? locality = raw_input("\nEnter City ") >? ? ? ? print locu_search(locality) >? ? ? ? break >? ? ? elif ans=="2": >? ? ? ? ? region = raw_input("\n Search by State ") >? ? ? ? ? print region_search(region) >? ? ? ? ? break >? ? ? elif ans=="3": >? ? ? ? ? zip = raw_input("\n Search by Zip ") >? ? ? ? ? print zip_search(zip) >? ? ? ? ? break >? ? ? elif ans=="4": >? ? ? ? print("\n Goodbye") >? ? ? ? break Because you now process the results in the if clauses you no longer need the breaks. In fact if you want the menu to be repeated you need to take them all out except for the last one. > ----- > I am not sure if above changes exactly reflect your suggestions but I tested the logic and it seems to work. > > The only issue is that on the first two queries (locu_search(locality) and > region_search(region)) I receive the following traceback error: > Traceback (most recent call last): >? ? File "C:/Users/dell/Documents/Python/MyProject/API_Projects/locu/locuAPI.py", line 47, in >? ? ? print locu_search(locality) >? ? File "C:/Users/dell/Documents/Python/MyProject/API_Projects/locu/locuAPI.py", line 14, in locu_search >? ? ? print item['name'], item['phone'], item['street_address'] >? ? File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode >? ? ? return codecs.charmap_encode(input,errors,encoding_table) > UnicodeEncodeError: 'charmap' codec can't encode character u'\u200e' in position 29: character maps to Looks like you are using cpl252 and your data is coming back as something else (UTF-8 maybe?) so you probably need to specify the encoding. -- 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